فهرست منبع

LibJS: Add BigInt64Array and BigUint64Array

This fixes ~297 test262 test cases :^)
Luke 4 سال پیش
والد
کامیت
9cbd90fdb6

+ 2 - 0
Userland/Libraries/LibJS/Forward.h

@@ -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)
 

+ 2 - 0
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.BYTES_PER_ELEMENT.js

@@ -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);
 });

+ 53 - 1
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.js

@@ -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", () => {

+ 2 - 1
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.BYTES_PER_ELEMENT.js

@@ -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 },
 ];

+ 22 - 1
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.at.js

@@ -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();
+    });
 });

+ 8 - 2
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.buffer.js

@@ -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;

+ 9 - 3
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.byteLength.js

@@ -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);
     });
 });

+ 10 - 4
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.byteOffset.js

@@ -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);
     });
 });

+ 2 - 1
Userland/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.length.js

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