1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 13:47:35 +00:00

LibJS: Implement missing steps from the ArrayBuffer transfer proposal

We can now implement steps related to resizable ArrayBuffer objects. We
can also implement a couple of missing SharedArrayBuffer checks.

The original implementation of this proposal did not have any tests, so
tests are added here for the whole implementation.
This commit is contained in:
Timothy Flynn 2023-12-28 08:55:38 -05:00 committed by Andreas Kling
parent 526a74f2f1
commit 3f3686cf7b
5 changed files with 201 additions and 8 deletions

View file

@ -0,0 +1,30 @@
describe("errors", () => {
test("called on non-ArrayBuffer object", () => {
expect(() => {
ArrayBuffer.prototype.detached;
}).toThrowWithMessage(TypeError, "Not an object of type ArrayBuffer");
});
test("called on SharedArrayBuffer object", () => {
let detached = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "detached");
let getter = detached.get;
expect(() => {
getter.call(new SharedArrayBuffer());
}).toThrowWithMessage(TypeError, "The array buffer object cannot be a SharedArrayBuffer");
});
});
describe("normal behavior", () => {
test("not detached", () => {
let buffer = new ArrayBuffer();
expect(buffer.detached).toBeFalse();
});
test("detached", () => {
let buffer = new ArrayBuffer();
detachArrayBuffer(buffer);
expect(buffer.detached).toBeTrue();
});
});

View file

@ -0,0 +1,76 @@
describe("errors", () => {
test("called on non-ArrayBuffer object", () => {
expect(() => {
ArrayBuffer.prototype.transfer(Symbol.hasInstance);
}).toThrowWithMessage(TypeError, "Not an object of type ArrayBuffer");
});
test("called on SharedArrayBuffer object", () => {
expect(() => {
ArrayBuffer.prototype.transfer.call(new SharedArrayBuffer());
}).toThrowWithMessage(TypeError, "The array buffer object cannot be a SharedArrayBuffer");
});
test("detached buffer", () => {
let buffer = new ArrayBuffer(5);
detachArrayBuffer(buffer);
expect(() => {
buffer.transfer();
}).toThrowWithMessage(TypeError, "ArrayBuffer is detached");
});
});
const readBuffer = buffer => {
let array = new Uint8Array(buffer, 0, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
let values = [];
for (let value of array) {
values.push(Number(value));
}
return values;
};
const writeBuffer = (buffer, values) => {
let array = new Uint8Array(buffer, 0, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
array.set(values);
};
describe("normal behavior", () => {
test("old buffer is detached", () => {
let buffer = new ArrayBuffer(5);
let newBuffer = buffer.transfer();
expect(buffer.detached).toBeTrue();
expect(newBuffer.detached).toBeFalse();
});
test("resizability is preserved", () => {
let buffer = new ArrayBuffer(5, { maxByteLength: 10 });
let newBuffer = buffer.transfer();
expect(buffer.resizable).toBeTrue();
expect(newBuffer.resizable).toBeTrue();
});
test("data is transferred", () => {
let buffer = new ArrayBuffer(5);
writeBuffer(buffer, [1, 2, 3, 4, 5]);
let newBuffer = buffer.transfer();
const values = readBuffer(newBuffer);
expect(values).toEqual([1, 2, 3, 4, 5]);
});
test("length may be limited", () => {
let buffer = new ArrayBuffer(5);
writeBuffer(buffer, [1, 2, 3, 4, 5]);
let newBuffer = buffer.transfer(3);
const values = readBuffer(newBuffer);
expect(values).toEqual([1, 2, 3]);
});
});

View file

@ -0,0 +1,76 @@
describe("errors", () => {
test("called on non-ArrayBuffer object", () => {
expect(() => {
ArrayBuffer.prototype.transferToFixedLength(Symbol.hasInstance);
}).toThrowWithMessage(TypeError, "Not an object of type ArrayBuffer");
});
test("called on SharedArrayBuffer object", () => {
expect(() => {
ArrayBuffer.prototype.transferToFixedLength.call(new SharedArrayBuffer());
}).toThrowWithMessage(TypeError, "The array buffer object cannot be a SharedArrayBuffer");
});
test("detached buffer", () => {
let buffer = new ArrayBuffer(5);
detachArrayBuffer(buffer);
expect(() => {
buffer.transferToFixedLength();
}).toThrowWithMessage(TypeError, "ArrayBuffer is detached");
});
});
const readBuffer = buffer => {
let array = new Uint8Array(buffer, 0, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
let values = [];
for (let value of array) {
values.push(Number(value));
}
return values;
};
const writeBuffer = (buffer, values) => {
let array = new Uint8Array(buffer, 0, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
array.set(values);
};
describe("normal behavior", () => {
test("old buffer is detached", () => {
let buffer = new ArrayBuffer(5);
let newBuffer = buffer.transferToFixedLength();
expect(buffer.detached).toBeTrue();
expect(newBuffer.detached).toBeFalse();
});
test("resizability is not preserved", () => {
let buffer = new ArrayBuffer(5, { maxByteLength: 10 });
let newBuffer = buffer.transferToFixedLength();
expect(buffer.resizable).toBeTrue();
expect(newBuffer.resizable).toBeFalse();
});
test("data is transferred", () => {
let buffer = new ArrayBuffer(5);
writeBuffer(buffer, [1, 2, 3, 4, 5]);
let newBuffer = buffer.transferToFixedLength();
const values = readBuffer(newBuffer);
expect(values).toEqual([1, 2, 3, 4, 5]);
});
test("length may be limited", () => {
let buffer = new ArrayBuffer(5);
writeBuffer(buffer, [1, 2, 3, 4, 5]);
let newBuffer = buffer.transferToFixedLength(3);
const values = readBuffer(newBuffer);
expect(values).toEqual([1, 2, 3]);
});
});