From 0aa54887c832b7408589d6dd7b67f75a66656654 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 29 Oct 2021 11:22:15 +0900 Subject: [PATCH] Quit Float16Array from inheriting from Uint16Array --- .eslintrc.json | 6 ++- src/Float16Array.mjs | 77 +++++++++++++++++---------------------- src/_util/primordials.mjs | 3 +- test/Float16Array.js | 2 +- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1bcc4b0b..0f72a3ff 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -21,7 +21,6 @@ "getter-return": "off", "indent": ["error", 2, { "SwitchCase": 1 }], "no-debugger": "warn", - "no-undef": "error", "no-restricted-globals": [ "error", "Array", @@ -74,6 +73,11 @@ "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array." } ], + "no-undef": "error", + "no-unused-vars": [ + "error", + { "argsIgnorePattern": "^_" } + ], "object-curly-spacing": ["error", "always"], "quotes": ["error", "double", "avoid-escape"], "semi": ["error", "always"], diff --git a/src/Float16Array.mjs b/src/Float16Array.mjs index 225c0cd5..95289a63 100644 --- a/src/Float16Array.mjs +++ b/src/Float16Array.mjs @@ -40,6 +40,7 @@ import { ObjectFreeze, ObjectHasOwn, ReflectApply, + ReflectConstruct, ReflectGet, ReflectGetOwnPropertyDescriptor, ReflectGetPrototypeOf, @@ -52,6 +53,7 @@ import { SymbolFor, SymbolIterator, SymbolToStringTag, + TypedArray, TypedArrayPrototype, TypedArrayPrototypeCopyWithin, TypedArrayPrototypeEntries, @@ -176,8 +178,11 @@ function getFloat16BitsArray(float16) { // from another Float16Array instance (a different version?) const cloned = new Float16Array( + // @ts-ignore float16.buffer, + // @ts-ignore float16.byteOffset, + // @ts-ignore float16.length ); return WeakMapPrototypeGet(targets, cloned); @@ -235,14 +240,15 @@ const handler = ObjectFreeze({ }, }); -/** limitation: `Object.getPrototypeOf(Float16Array)` returns `Uint16Array` */ -export class Float16Array extends NativeUint16Array { +export class Float16Array { /** @see https://tc39.es/ecma262/#sec-typedarray */ - constructor(input, byteOffset, length) { + constructor(input, _byteOffset, _length) { + /** @type {Uint16Array & { __float16bits: never }} */ + let float16bitsArray; + if (isFloat16Array(input)) { // peel off Proxy - const float16bitsArray = getFloat16BitsArray(input); - super(float16bitsArray); + float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target); } else if (isObject(input) && !isArrayBuffer(input)) { // object without ArrayBuffer /** @type {ArrayLike} */ let list; @@ -269,57 +275,37 @@ export class Float16Array extends NativeUint16Array { const data = new BufferConstructor( length * BYTES_PER_ELEMENT ); - super(data); - } else if (isIterable(input)) { // Iterable (Array) - // for optimization - if (isOrdinaryArray(input)) { - list = input; - length = input.length; - super(length); - } else { - list = [...input]; - length = list.length; - super(length); + float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target); + } else { + if (isIterable(input)) { // Iterable (Array) + // for optimization + if (isOrdinaryArray(input)) { + list = input; + length = input.length; + } else { + list = [...input]; + length = list.length; + } + } else { // ArrayLike + list = /** @type {ArrayLike} */ (input); + length = LengthOfArrayLike(input); } - } else { // ArrayLike - list = /** @type {ArrayLike} */ (input); - length = LengthOfArrayLike(input); - super(length); + float16bitsArray = ReflectConstruct(NativeUint16Array, [length], new.target); } // set values for (let i = 0; i < length; ++i) { // super (Uint16Array) - this[i] = roundToFloat16Bits(list[i]); + float16bitsArray[i] = roundToFloat16Bits(list[i]); } } else { // primitive, ArrayBuffer - switch (arguments.length) { - case 0: - super(); - break; - - case 1: - super(input); - break; - - case 2: - super(input, byteOffset); - break; - - case 3: - super(input, byteOffset, length); - break; - - default: - // @ts-ignore - super(...arguments); - } + float16bitsArray = ReflectConstruct(NativeUint16Array, arguments, new.target); } - const proxy = new NativeProxy(this, handler); + const proxy = new NativeProxy(/** @type {any} */ (float16bitsArray), handler); // proxy private storage - WeakMapPrototypeSet(targets, proxy, /** @type {any} */ (this)); + WeakMapPrototypeSet(targets, proxy, float16bitsArray); return proxy; } @@ -1069,6 +1055,9 @@ ObjectDefineProperty(Float16Array, "BYTES_PER_ELEMENT", { // limitation: It is peaked by `Object.getOwnPropertySymbols(Float16Array)` and `Reflect.ownKeys(Float16Array)` ObjectDefineProperty(Float16Array, brand, {}); +/** @see https://tc39.es/ecma262/#sec-properties-of-the-typedarray-constructors */ +ReflectSetPrototypeOf(Float16Array, TypedArray); + const Float16ArrayPrototype = Float16Array.prototype; /** @see https://tc39.es/ecma262/#sec-typedarray.prototype.bytes_per_element */ diff --git a/src/_util/primordials.mjs b/src/_util/primordials.mjs index 80272ee5..7c817724 100644 --- a/src/_util/primordials.mjs +++ b/src/_util/primordials.mjs @@ -18,6 +18,7 @@ function uncurryThisGetter(target, key) { // Reflect export const { apply: ReflectApply, + construct: ReflectConstruct, get: ReflectGet, getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, getPrototypeOf: ReflectGetPrototypeOf, @@ -79,7 +80,7 @@ export const NativeArrayBuffer = ArrayBuffer; // TypedArray /** @typedef {Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array|BigUint64Array|BigInt64Array} TypedArray */ /** @type {any} */ -const TypedArray = ReflectGetPrototypeOf(Uint8Array); +export const TypedArray = ReflectGetPrototypeOf(Uint8Array); export const TypedArrayPrototype = TypedArray.prototype; /** @type {(typedArray: TypedArray) => IterableIterator} */ export const TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys); diff --git a/test/Float16Array.js b/test/Float16Array.js index 2950d788..4ef51165 100644 --- a/test/Float16Array.js +++ b/test/Float16Array.js @@ -1466,7 +1466,7 @@ describe("Float16Array", () => { } } const bar = new Bar([1, 2, 3, 4]); - assert.throws(() => bar.slice(), Error); + assert.throws(() => bar.slice(), TypeError); }); describe("#subarray()", () => {