Skip to content

Commit

Permalink
Fix Float16Array constructor for SharedArrayBuffer (#1025)
Browse files Browse the repository at this point in the history
  • Loading branch information
petamoriken authored Aug 13, 2023
1 parent 3274344 commit d9190ed
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/Float16Array.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { safeIfNeeded, wrap } from "./_util/arrayIterator.mjs";
import { brand, hasFloat16ArrayBrand } from "./_util/brand.mjs";
import { convertToNumber, roundToFloat16Bits } from "./_util/converter.mjs";
import {
isArrayBuffer,
isAnyArrayBuffer,
isCanonicalIntegerIndexString,
isNativeBigIntTypedArray,
isNativeTypedArray,
Expand Down Expand Up @@ -259,7 +259,7 @@ export class Float16Array {

if (isFloat16Array(input)) {
float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target);
} else if (isObject(input) && !isArrayBuffer(input)) { // object without ArrayBuffer
} else if (isObject(input) && !isAnyArrayBuffer(input)) { // object without ArrayBuffer, SharedArrayBuffer
/** @type {ArrayLike<unknown>} */
let list;
/** @type {number} */
Expand Down Expand Up @@ -310,7 +310,7 @@ export class Float16Array {
for (let i = 0; i < length; ++i) {
float16bitsArray[i] = roundToFloat16Bits(list[i]);
}
} else { // primitive, ArrayBuffer
} else { // primitive, ArrayBuffer, SharedArrayBuffer
float16bitsArray = ReflectConstruct(NativeUint16Array, arguments, new.target);
}

Expand Down
10 changes: 9 additions & 1 deletion src/_util/is.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function isNativeBigIntTypedArray(value) {
* @param {unknown} value
* @returns {value is ArrayBuffer}
*/
export function isArrayBuffer(value) {
function isArrayBuffer(value) {
try {
ArrayBufferPrototypeGetByteLength(/** @type {any} */ (value));
return true;
Expand All @@ -85,6 +85,14 @@ export function isSharedArrayBuffer(value) {
}
}

/**
* @param {unknown} value
* @returns {value is ArrayBuffer|SharedArrayBuffer}
*/
export function isAnyArrayBuffer(value) {
return isArrayBuffer(value) || isSharedArrayBuffer(value);
}

/**
* @param {unknown} value
* @returns {value is unknown[]}
Expand Down
36 changes: 36 additions & 0 deletions test/Float16Array.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,42 @@ describe("Float16Array", () => {
const detachedBuffer = detach(new ArrayBuffer(4));
assert.throws(() => new Float16Array(detachedBuffer), TypeError);
});

it("input SharedArrayBuffer", function () {
if (typeof SharedArrayBuffer === "undefined") {
this.skip();
}

const buffer = new SharedArrayBuffer(8);
const uint16 = new Uint16Array(buffer);
uint16[0] = 15360;
uint16[1] = 15462;
uint16[2] = 15565;
uint16[3] = 15667;

const float16_1 = new Float16Array(buffer);

assert(float16_1.BYTES_PER_ELEMENT === 2);
assert(float16_1.buffer === buffer);
assert(float16_1.byteOffset === 0);
assert(float16_1.byteLength === 8);
assert(float16_1.length === 4);
assert.equalFloat16ArrayValues(float16_1, [
1,
1.099609375,
1.2001953125,
1.2998046875,
]);

const float16_2 = new Float16Array(buffer, 2, 2);

assert(float16_2.BYTES_PER_ELEMENT === 2);
assert(float16_2.buffer === buffer);
assert(float16_2.byteOffset === 2);
assert(float16_2.byteLength === 4);
assert(float16_2.length === 2);
assert.equalFloat16ArrayValues(float16_2, [1.099609375, 1.2001953125]);
});
});

describe(".from()", () => {
Expand Down

0 comments on commit d9190ed

Please sign in to comment.