LibJS: Add BigInt64Array and BigUint64Array

This fixes ~297 test262 test cases :^)
This commit is contained in:
Luke 2021-06-17 01:37:23 +01:00 committed by Linus Groh
parent 411c72da27
commit 9cbd90fdb6
Notes: sideshowbarker 2024-07-18 12:08:49 +09:00
9 changed files with 110 additions and 13 deletions

View File

@ -67,9 +67,11 @@
__JS_ENUMERATE(Uint8ClampedArray, uint8_clamped_array, Uint8ClampedArrayPrototype, Uint8ClampedArrayConstructor, ClampedU8) \
__JS_ENUMERATE(Uint16Array, uint16_array, Uint16ArrayPrototype, Uint16ArrayConstructor, u16) \
__JS_ENUMERATE(Uint32Array, uint32_array, Uint32ArrayPrototype, Uint32ArrayConstructor, u32) \
__JS_ENUMERATE(BigUint64Array, big_uint64_array, BigUint64ArrayPrototype, BigUint64ArrayConstructor, u64) \
__JS_ENUMERATE(Int8Array, int8_array, Int8ArrayPrototype, Int8ArrayConstructor, i8) \
__JS_ENUMERATE(Int16Array, int16_array, Int16ArrayPrototype, Int16ArrayConstructor, i16) \
__JS_ENUMERATE(Int32Array, int32_array, Int32ArrayPrototype, Int32ArrayConstructor, i32) \
__JS_ENUMERATE(BigInt64Array, big_int64_array, BigInt64ArrayPrototype, BigInt64ArrayConstructor, i64) \
__JS_ENUMERATE(Float32Array, float32_array, Float32ArrayPrototype, Float32ArrayConstructor, float) \
__JS_ENUMERATE(Float64Array, float64_array, Float64ArrayPrototype, Float64ArrayConstructor, double)

View File

@ -2,9 +2,11 @@ test("basic functionality", () => {
expect(Uint8Array.BYTES_PER_ELEMENT).toBe(1);
expect(Uint16Array.BYTES_PER_ELEMENT).toBe(2);
expect(Uint32Array.BYTES_PER_ELEMENT).toBe(4);
expect(BigUint64Array.BYTES_PER_ELEMENT).toBe(8);
expect(Int8Array.BYTES_PER_ELEMENT).toBe(1);
expect(Int16Array.BYTES_PER_ELEMENT).toBe(2);
expect(Int32Array.BYTES_PER_ELEMENT).toBe(4);
expect(BigInt64Array.BYTES_PER_ELEMENT).toBe(8);
expect(Float32Array.BYTES_PER_ELEMENT).toBe(4);
expect(Float64Array.BYTES_PER_ELEMENT).toBe(8);
});

View File

@ -1,4 +1,3 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
Uint8Array,
Uint16Array,
@ -10,6 +9,8 @@ const TYPED_ARRAYS = [
Float64Array,
];
const BIGINT_TYPED_ARRAYS = [BigUint64Array, BigInt64Array];
const getTypedArrayConstructor = () => Object.getPrototypeOf(TYPED_ARRAYS[0]);
test("basic functionality", () => {
@ -20,6 +21,9 @@ test("basic functionality", () => {
TYPED_ARRAYS.forEach(T => {
expect(T.prototype.constructor).toBe(T);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(T.prototype.constructor).toBe(T);
});
const FunctionPrototype = Object.getPrototypeOf(() => {});
expect(Object.getPrototypeOf(TypedArray)).toBe(FunctionPrototype);
});
@ -30,6 +34,11 @@ test("typed array constructors must be invoked with 'new'", () => {
T();
}).toThrowWithMessage(TypeError, `${T.name} constructor must be called with 'new'`);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(() => {
T();
}).toThrowWithMessage(TypeError, `${T.name} constructor must be called with 'new'`);
});
});
test("typed array constructors have TypedArray as prototype", () => {
@ -37,6 +46,9 @@ test("typed array constructors have TypedArray as prototype", () => {
TYPED_ARRAYS.forEach(T => {
expect(Object.getPrototypeOf(T)).toBe(TypedArray);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(Object.getPrototypeOf(T)).toBe(TypedArray);
});
});
test("typed array prototypes have TypedArray.prototype as prototype", () => {
@ -45,6 +57,10 @@ test("typed array prototypes have TypedArray.prototype as prototype", () => {
const TPrototype = Object.getPrototypeOf(new T());
expect(Object.getPrototypeOf(TPrototype)).toBe(TypedArray.prototype);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
const TPrototype = Object.getPrototypeOf(new T());
expect(Object.getPrototypeOf(TPrototype)).toBe(TypedArray.prototype);
});
});
test("typed arrays inherit from TypedArray", () => {
@ -52,6 +68,9 @@ test("typed arrays inherit from TypedArray", () => {
TYPED_ARRAYS.forEach(T => {
expect(new T()).toBeInstanceOf(TypedArray);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(new T()).toBeInstanceOf(TypedArray);
});
});
test("typed array can share the same ArrayBuffer", () => {
@ -130,6 +149,22 @@ test("typed array from TypedArray", () => {
expect(newTypedArray[1]).toBe(2);
expect(newTypedArray[2]).toBe(3);
});
const bigU64Array = new BigUint64Array(3);
bigU64Array[0] = 1n;
bigU64Array[1] = 2n;
bigU64Array[2] = 3n;
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(() => {
const newTypedArray = new T(u8Array);
}).toThrowWithMessage(TypeError, "Cannot convert number to BigInt");
const newBigIntTypedArray = new T(bigU64Array);
expect(newBigIntTypedArray[0]).toBe(1n);
expect(newBigIntTypedArray[1]).toBe(2n);
expect(newBigIntTypedArray[2]).toBe(3n);
});
});
test("typed array from TypedArray element cast", () => {
@ -193,6 +228,16 @@ test("typed array from Array-Like", () => {
}
func(1, 2, 3);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
function func() {
const newTypedArray = new T(arguments);
expect(newTypedArray[0]).toBe(1n);
expect(newTypedArray[1]).toBe(2n);
expect(newTypedArray[2]).toBe(3n);
}
func(1n, 2n, 3n);
});
});
test("typed array from Iterable", () => {
@ -204,6 +249,13 @@ test("typed array from Iterable", () => {
expect(newTypedArray[1]).toBe(2);
expect(newTypedArray[2]).toBe(3);
});
BIGINT_TYPED_ARRAYS.forEach(T => {
const newTypedArray = new T(from);
expect(newTypedArray[0]).toBe(1n);
expect(newTypedArray[1]).toBe(2n);
expect(newTypedArray[2]).toBe(3n);
});
});
test("TypedArray is not exposed on the global object", () => {

View File

@ -1,11 +1,12 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
{ array: Uint8Array, expected: 1 },
{ array: Uint16Array, expected: 2 },
{ array: Uint32Array, expected: 4 },
{ array: BigUint64Array, expected: 8 },
{ array: Int8Array, expected: 1 },
{ array: Int16Array, expected: 2 },
{ array: Int32Array, expected: 4 },
{ array: BigInt64Array, expected: 8 },
{ array: Float32Array, expected: 4 },
{ array: Float64Array, expected: 8 },
];

View File

@ -1,4 +1,3 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
Uint8Array,
Uint16Array,
@ -10,6 +9,8 @@ const TYPED_ARRAYS = [
Float64Array,
];
const BIGINT_TYPED_ARRAYS = [BigUint64Array, BigInt64Array];
test("basic functionality", () => {
TYPED_ARRAYS.forEach(T => {
expect(T.prototype.at).toHaveLength(1);
@ -30,4 +31,24 @@ test("basic functionality", () => {
expect(typedArray.at(-4)).toBeUndefined();
expect(typedArray.at(-Infinity)).toBeUndefined();
});
BIGINT_TYPED_ARRAYS.forEach(T => {
expect(T.prototype.at).toHaveLength(1);
const typedArray = new T(3);
typedArray[0] = 1n;
typedArray[1] = 2n;
typedArray[2] = 3n;
expect(typedArray.at(0)).toBe(1n);
expect(typedArray.at(1)).toBe(2n);
expect(typedArray.at(2)).toBe(3n);
expect(typedArray.at(3)).toBeUndefined();
expect(typedArray.at(Infinity)).toBeUndefined();
expect(typedArray.at(-1)).toBe(3n);
expect(typedArray.at(-2)).toBe(2n);
expect(typedArray.at(-3)).toBe(1n);
expect(typedArray.at(-4)).toBeUndefined();
expect(typedArray.at(-Infinity)).toBeUndefined();
});
});

View File

@ -1,18 +1,24 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
Uint8Array,
Uint16Array,
Uint32Array,
BigUint64Array,
Int8Array,
Int16Array,
Int32Array,
BigInt64Array,
Float32Array,
Float64Array,
];
test("basic functionality", () => {
TYPED_ARRAYS.forEach(T => {
const typedArray = new T([1, 2, 3]);
const isBigIntArray = T === BigInt64Array || T === BigUint64Array;
let typedArray;
if (!isBigIntArray) typedArray = new T([1, 2, 3]);
else typedArray = new T([1n, 2n, 3n]);
expect(Object.hasOwn(typedArray, "byteOffset")).toBeFalse();
const buffer = typedArray.buffer;

View File

@ -1,19 +1,25 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
{ array: Uint8Array, expected: 3 },
{ array: Uint16Array, expected: 6 },
{ array: Uint32Array, expected: 12 },
{ array: BigUint64Array, expected: 24 },
{ array: Int8Array, expected: 3 },
{ array: Int16Array, expected: 6 },
{ array: Int32Array, expected: 12 },
{ array: BigInt64Array, expected: 24 },
{ array: Float32Array, expected: 12 },
{ array: Float64Array, expected: 24 },
];
test("basic functionality", () => {
TYPED_ARRAYS.forEach(T => {
const typedArray = new T.array([1, 2, 3]);
expect(Object.hasOwn(typedArray, "byteLength")).toBeFalse();
const isBigIntArray = T.array === BigInt64Array || T.array === BigUint64Array;
let typedArray;
if (!isBigIntArray) typedArray = new T.array([1, 2, 3]);
else typedArray = new T.array([1n, 2n, 3n]);
expect(Object.hasOwn(typedArray, "byteOffset")).toBeFalse();
expect(typedArray.byteLength).toBe(T.expected);
});
});

View File

@ -1,18 +1,24 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
Uint8Array,
Uint16Array,
Uint32Array,
BigUint64Array,
Int8Array,
Int16Array,
Int32Array,
BigInt64Array,
Float32Array,
Float64Array,
];
test("basic functionality", () => {
TYPED_ARRAYS.forEach(T => {
const typedArray = new T([1, 2, 3]);
const isBigIntArray = T === BigInt64Array || T === BigUint64Array;
let typedArray;
if (!isBigIntArray) typedArray = new T([1, 2, 3]);
else typedArray = new T([1n, 2n, 3n]);
expect(Object.hasOwn(typedArray, "byteOffset")).toBeFalse();
expect(typedArray.byteOffset).toBe(0);
expect(typedArray.length).toBe(3);
@ -22,7 +28,7 @@ test("basic functionality", () => {
const arrayFromOffset = new T(buffer, T.BYTES_PER_ELEMENT);
expect(arrayFromOffset.byteOffset).toBe(T.BYTES_PER_ELEMENT);
expect(arrayFromOffset.length).toBe(2);
expect(arrayFromOffset[0]).toBe(2);
expect(arrayFromOffset[1]).toBe(3);
expect(arrayFromOffset[0]).toBe(!isBigIntArray ? 2 : 2n);
expect(arrayFromOffset[1]).toBe(!isBigIntArray ? 3 : 3n);
});
});

View File

@ -1,11 +1,12 @@
// Update when more typed arrays get added
const TYPED_ARRAYS = [
Uint8Array,
Uint16Array,
Uint32Array,
BigUint64Array,
Int8Array,
Int16Array,
Int32Array,
BigInt64Array,
Float32Array,
Float64Array,
];