Skip to content

Commit

Permalink
Quit Float16Array from inheriting from Uint16Array
Browse files Browse the repository at this point in the history
  • Loading branch information
petamoriken committed Oct 29, 2021
1 parent 6790e79 commit 0aa5488
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 47 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"getter-return": "off",
"indent": ["error", 2, { "SwitchCase": 1 }],
"no-debugger": "warn",
"no-undef": "error",
"no-restricted-globals": [
"error",
"Array",
Expand Down Expand Up @@ -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"],
Expand Down
77 changes: 33 additions & 44 deletions src/Float16Array.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
ObjectFreeze,
ObjectHasOwn,
ReflectApply,
ReflectConstruct,
ReflectGet,
ReflectGetOwnPropertyDescriptor,
ReflectGetPrototypeOf,
Expand All @@ -52,6 +53,7 @@ import {
SymbolFor,
SymbolIterator,
SymbolToStringTag,
TypedArray,
TypedArrayPrototype,
TypedArrayPrototypeCopyWithin,
TypedArrayPrototypeEntries,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<unknown>} */
let list;
Expand All @@ -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<unknown>} */ (input);
length = LengthOfArrayLike(input);
}
} else { // ArrayLike
list = /** @type {ArrayLike<unknown>} */ (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;
}
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 2 additions & 1 deletion src/_util/primordials.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function uncurryThisGetter(target, key) {
// Reflect
export const {
apply: ReflectApply,
construct: ReflectConstruct,
get: ReflectGet,
getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor,
getPrototypeOf: ReflectGetPrototypeOf,
Expand Down Expand Up @@ -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<number>} */
export const TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys);
Expand Down
2 changes: 1 addition & 1 deletion test/Float16Array.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()", () => {
Expand Down

0 comments on commit 0aa5488

Please sign in to comment.