Float16Array.mjs 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. import { safeIfNeeded, wrap } from "./_util/arrayIterator.mjs";
  2. import { brand, hasFloat16ArrayBrand } from "./_util/brand.mjs";
  3. import { convertToNumber, roundToFloat16Bits } from "./_util/converter.mjs";
  4. import {
  5. isArrayBuffer,
  6. isCanonicalIntegerIndexString,
  7. isNativeBigIntTypedArray,
  8. isNativeTypedArray,
  9. isObject,
  10. isOrdinaryArray,
  11. isOrdinaryNativeTypedArray,
  12. } from "./_util/is.mjs";
  13. import {
  14. ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER,
  15. CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT,
  16. CANNOT_MIX_BIGINT_AND_OTHER_TYPES,
  17. DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH,
  18. ITERATOR_PROPERTY_IS_NOT_CALLABLE,
  19. OFFSET_IS_OUT_OF_BOUNDS,
  20. REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE,
  21. SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT,
  22. THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED,
  23. THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY,
  24. THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT,
  25. } from "./_util/messages.mjs";
  26. import {
  27. ArrayBufferIsView,
  28. ArrayPrototypeJoin,
  29. ArrayPrototypePush,
  30. ArrayPrototypeToLocaleString,
  31. NativeArrayBuffer,
  32. NativeObject,
  33. NativeProxy,
  34. NativeRangeError,
  35. NativeTypeError,
  36. NativeUint16Array,
  37. NativeWeakMap,
  38. NativeWeakSet,
  39. NumberIsNaN,
  40. ObjectDefineProperty,
  41. ObjectFreeze,
  42. ObjectHasOwn,
  43. ObjectPrototype__lookupGetter__,
  44. ReflectApply,
  45. ReflectConstruct,
  46. ReflectDefineProperty,
  47. ReflectGet,
  48. ReflectGetOwnPropertyDescriptor,
  49. ReflectHas,
  50. ReflectOwnKeys,
  51. ReflectSet,
  52. ReflectSetPrototypeOf,
  53. SymbolIterator,
  54. SymbolToStringTag,
  55. TypedArray,
  56. TypedArrayPrototype,
  57. TypedArrayPrototypeCopyWithin,
  58. TypedArrayPrototypeEntries,
  59. TypedArrayPrototypeFill,
  60. TypedArrayPrototypeGetBuffer,
  61. TypedArrayPrototypeGetByteOffset,
  62. TypedArrayPrototypeGetLength,
  63. TypedArrayPrototypeKeys,
  64. TypedArrayPrototypeReverse,
  65. TypedArrayPrototypeSet,
  66. TypedArrayPrototypeSlice,
  67. TypedArrayPrototypeSort,
  68. TypedArrayPrototypeSubarray,
  69. TypedArrayPrototypeValues,
  70. Uint16ArrayFrom,
  71. WeakMapPrototypeGet,
  72. WeakMapPrototypeHas,
  73. WeakMapPrototypeSet,
  74. WeakSetPrototypeAdd,
  75. WeakSetPrototypeHas,
  76. } from "./_util/primordials.mjs";
  77. import {
  78. IsDetachedBuffer,
  79. SpeciesConstructor,
  80. ToIntegerOrInfinity,
  81. ToLength,
  82. defaultCompare,
  83. } from "./_util/spec.mjs";
  84. const BYTES_PER_ELEMENT = 2;
  85. /** @typedef {Uint16Array & { __float16bits: never }} Float16BitsArray */
  86. /** @type {WeakMap<Float16Array, Float16BitsArray>} */
  87. const float16bitsArrays = new NativeWeakMap();
  88. /**
  89. * @param {unknown} target
  90. * @returns {target is Float16Array}
  91. */
  92. export function isFloat16Array(target) {
  93. return WeakMapPrototypeHas(float16bitsArrays, target) ||
  94. (!ArrayBufferIsView(target) && hasFloat16ArrayBrand(target));
  95. }
  96. /**
  97. * @param {unknown} target
  98. * @throws {TypeError}
  99. * @returns {asserts target is Float16Array}
  100. */
  101. function assertFloat16Array(target) {
  102. if (!isFloat16Array(target)) {
  103. throw NativeTypeError(THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT);
  104. }
  105. }
  106. /**
  107. * @param {unknown} target
  108. * @param {number=} count
  109. * @throws {TypeError}
  110. * @returns {asserts target is Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float16Array|Float32Array|Float64Array}
  111. */
  112. function assertSpeciesTypedArray(target, count) {
  113. const isTargetFloat16Array = isFloat16Array(target);
  114. const isTargetTypedArray = isNativeTypedArray(target);
  115. if (!isTargetFloat16Array && !isTargetTypedArray) {
  116. throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT);
  117. }
  118. if (typeof count === "number") {
  119. let length;
  120. if (isTargetFloat16Array) {
  121. const float16bitsArray = getFloat16BitsArray(target);
  122. length = TypedArrayPrototypeGetLength(float16bitsArray);
  123. } else {
  124. length = TypedArrayPrototypeGetLength(target);
  125. }
  126. if (length < count) {
  127. throw NativeTypeError(
  128. DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH
  129. );
  130. }
  131. }
  132. if (isNativeBigIntTypedArray(target)) {
  133. throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
  134. }
  135. }
  136. /**
  137. * @param {Float16Array} float16
  138. * @throws {TypeError}
  139. * @returns {Float16BitsArray}
  140. */
  141. function getFloat16BitsArray(float16) {
  142. const float16bitsArray = WeakMapPrototypeGet(float16bitsArrays, float16);
  143. if (float16bitsArray !== undefined) {
  144. const buffer = TypedArrayPrototypeGetBuffer(float16bitsArray);
  145. if (IsDetachedBuffer(buffer)) {
  146. throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
  147. }
  148. return float16bitsArray;
  149. }
  150. // from another Float16Array instance (a different version?)
  151. const buffer = /** @type {any} */ (float16).buffer;
  152. if (IsDetachedBuffer(buffer)) {
  153. throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
  154. }
  155. const cloned = ReflectConstruct(Float16Array, [
  156. buffer,
  157. /** @type {any} */ (float16).byteOffset,
  158. /** @type {any} */ (float16).length,
  159. ], float16.constructor);
  160. return WeakMapPrototypeGet(float16bitsArrays, cloned);
  161. }
  162. /**
  163. * @param {Float16BitsArray} float16bitsArray
  164. * @returns {number[]}
  165. */
  166. function copyToArray(float16bitsArray) {
  167. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  168. const array = [];
  169. for (let i = 0; i < length; ++i) {
  170. array[i] = convertToNumber(float16bitsArray[i]);
  171. }
  172. return array;
  173. }
  174. /** @type {WeakSet<Function>} */
  175. const TypedArrayPrototypeGetters = new NativeWeakSet();
  176. for (const key of ReflectOwnKeys(TypedArrayPrototype)) {
  177. // @@toStringTag getter property is defined in Float16Array.prototype
  178. if (key === SymbolToStringTag) {
  179. continue;
  180. }
  181. const descriptor = ReflectGetOwnPropertyDescriptor(TypedArrayPrototype, key);
  182. if (ObjectHasOwn(descriptor, "get") && typeof descriptor.get === "function") {
  183. WeakSetPrototypeAdd(TypedArrayPrototypeGetters, descriptor.get);
  184. }
  185. }
  186. const handler = ObjectFreeze(/** @type {ProxyHandler<Float16BitsArray>} */ ({
  187. get(target, key, receiver) {
  188. if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
  189. return convertToNumber(ReflectGet(target, key));
  190. }
  191. // %TypedArray%.prototype getter properties cannot called by Proxy receiver
  192. if (WeakSetPrototypeHas(TypedArrayPrototypeGetters, ObjectPrototype__lookupGetter__(target, key))) {
  193. return ReflectGet(target, key);
  194. }
  195. return ReflectGet(target, key, receiver);
  196. },
  197. set(target, key, value, receiver) {
  198. if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
  199. return ReflectSet(target, key, roundToFloat16Bits(value));
  200. }
  201. return ReflectSet(target, key, value, receiver);
  202. },
  203. getOwnPropertyDescriptor(target, key) {
  204. if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
  205. const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
  206. descriptor.value = convertToNumber(descriptor.value);
  207. return descriptor;
  208. }
  209. return ReflectGetOwnPropertyDescriptor(target, key);
  210. },
  211. defineProperty(target, key, descriptor) {
  212. if (
  213. isCanonicalIntegerIndexString(key) &&
  214. ObjectHasOwn(target, key) &&
  215. ObjectHasOwn(descriptor, "value")
  216. ) {
  217. descriptor.value = roundToFloat16Bits(descriptor.value);
  218. return ReflectDefineProperty(target, key, descriptor);
  219. }
  220. return ReflectDefineProperty(target, key, descriptor);
  221. },
  222. }));
  223. export class Float16Array {
  224. /** @see https://tc39.es/ecma262/#sec-typedarray */
  225. constructor(input, _byteOffset, _length) {
  226. /** @type {Float16BitsArray} */
  227. let float16bitsArray;
  228. if (isFloat16Array(input)) {
  229. float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target);
  230. } else if (isObject(input) && !isArrayBuffer(input)) { // object without ArrayBuffer
  231. /** @type {ArrayLike<unknown>} */
  232. let list;
  233. /** @type {number} */
  234. let length;
  235. if (isNativeTypedArray(input)) { // TypedArray
  236. list = input;
  237. length = TypedArrayPrototypeGetLength(input);
  238. const buffer = TypedArrayPrototypeGetBuffer(input);
  239. if (IsDetachedBuffer(buffer)) {
  240. throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
  241. }
  242. if (isNativeBigIntTypedArray(input)) {
  243. throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
  244. }
  245. const data = new NativeArrayBuffer(
  246. length * BYTES_PER_ELEMENT
  247. );
  248. float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target);
  249. } else {
  250. const iterator = input[SymbolIterator];
  251. if (iterator != null && typeof iterator !== "function") {
  252. throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
  253. }
  254. if (iterator != null) { // Iterable (Array)
  255. // for optimization
  256. if (isOrdinaryArray(input)) {
  257. list = input;
  258. length = input.length;
  259. } else {
  260. // eslint-disable-next-line no-restricted-syntax
  261. list = [... /** @type {Iterable<unknown>} */ (input)];
  262. length = list.length;
  263. }
  264. } else { // ArrayLike
  265. list = /** @type {ArrayLike<unknown>} */ (input);
  266. length = ToLength(list.length);
  267. }
  268. float16bitsArray = ReflectConstruct(NativeUint16Array, [length], new.target);
  269. }
  270. // set values
  271. for (let i = 0; i < length; ++i) {
  272. float16bitsArray[i] = roundToFloat16Bits(list[i]);
  273. }
  274. } else { // primitive, ArrayBuffer
  275. float16bitsArray = ReflectConstruct(NativeUint16Array, arguments, new.target);
  276. }
  277. /** @type {Float16Array} */
  278. const proxy = /** @type {any} */ (new NativeProxy(float16bitsArray, handler));
  279. // proxy private storage
  280. WeakMapPrototypeSet(float16bitsArrays, proxy, float16bitsArray);
  281. return proxy;
  282. }
  283. /**
  284. * limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
  285. *
  286. * @see https://tc39.es/ecma262/#sec-%typedarray%.from
  287. */
  288. static from(src, ...opts) {
  289. const Constructor = this;
  290. if (!ReflectHas(Constructor, brand)) {
  291. throw NativeTypeError(
  292. THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
  293. );
  294. }
  295. // for optimization
  296. if (Constructor === Float16Array) {
  297. if (isFloat16Array(src) && opts.length === 0) {
  298. const float16bitsArray = getFloat16BitsArray(src);
  299. const uint16 = new NativeUint16Array(
  300. TypedArrayPrototypeGetBuffer(float16bitsArray),
  301. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  302. TypedArrayPrototypeGetLength(float16bitsArray)
  303. );
  304. return new Float16Array(
  305. TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16))
  306. );
  307. }
  308. if (opts.length === 0) {
  309. return new Float16Array(
  310. TypedArrayPrototypeGetBuffer(
  311. Uint16ArrayFrom(src, roundToFloat16Bits)
  312. )
  313. );
  314. }
  315. const mapFunc = opts[0];
  316. const thisArg = opts[1];
  317. return new Float16Array(
  318. TypedArrayPrototypeGetBuffer(
  319. Uint16ArrayFrom(src, function (val, ...args) {
  320. return roundToFloat16Bits(
  321. ReflectApply(mapFunc, this, [val, ...safeIfNeeded(args)])
  322. );
  323. }, thisArg)
  324. )
  325. );
  326. }
  327. /** @type {ArrayLike<unknown>} */
  328. let list;
  329. /** @type {number} */
  330. let length;
  331. const iterator = src[SymbolIterator];
  332. if (iterator != null && typeof iterator !== "function") {
  333. throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
  334. }
  335. if (iterator != null) { // Iterable (TypedArray, Array)
  336. // for optimization
  337. if (isOrdinaryArray(src)) {
  338. list = src;
  339. length = src.length;
  340. } else if (isOrdinaryNativeTypedArray(src)) {
  341. list = src;
  342. length = TypedArrayPrototypeGetLength(src);
  343. } else {
  344. // eslint-disable-next-line no-restricted-syntax
  345. list = [...src];
  346. length = list.length;
  347. }
  348. } else { // ArrayLike
  349. if (src == null) {
  350. throw NativeTypeError(
  351. CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
  352. );
  353. }
  354. list = NativeObject(src);
  355. length = ToLength(list.length);
  356. }
  357. const array = new Constructor(length);
  358. if (opts.length === 0) {
  359. for (let i = 0; i < length; ++i) {
  360. array[i] = /** @type {number} */ (list[i]);
  361. }
  362. } else {
  363. const mapFunc = opts[0];
  364. const thisArg = opts[1];
  365. for (let i = 0; i < length; ++i) {
  366. array[i] = ReflectApply(mapFunc, thisArg, [list[i], i]);
  367. }
  368. }
  369. return array;
  370. }
  371. /**
  372. * limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
  373. *
  374. * @see https://tc39.es/ecma262/#sec-%typedarray%.of
  375. */
  376. static of(...items) {
  377. const Constructor = this;
  378. if (!ReflectHas(Constructor, brand)) {
  379. throw NativeTypeError(
  380. THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
  381. );
  382. }
  383. const length = items.length;
  384. // for optimization
  385. if (Constructor === Float16Array) {
  386. const proxy = new Float16Array(length);
  387. const float16bitsArray = getFloat16BitsArray(proxy);
  388. for (let i = 0; i < length; ++i) {
  389. float16bitsArray[i] = roundToFloat16Bits(items[i]);
  390. }
  391. return proxy;
  392. }
  393. const array = new Constructor(length);
  394. for (let i = 0; i < length; ++i) {
  395. array[i] = items[i];
  396. }
  397. return array;
  398. }
  399. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys */
  400. keys() {
  401. assertFloat16Array(this);
  402. const float16bitsArray = getFloat16BitsArray(this);
  403. return TypedArrayPrototypeKeys(float16bitsArray);
  404. }
  405. /**
  406. * limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
  407. *
  408. * @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.values
  409. */
  410. values() {
  411. assertFloat16Array(this);
  412. const float16bitsArray = getFloat16BitsArray(this);
  413. return wrap((function* () {
  414. // eslint-disable-next-line no-restricted-syntax
  415. for (const val of TypedArrayPrototypeValues(float16bitsArray)) {
  416. yield convertToNumber(val);
  417. }
  418. })());
  419. }
  420. /**
  421. * limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
  422. *
  423. * @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries
  424. */
  425. entries() {
  426. assertFloat16Array(this);
  427. const float16bitsArray = getFloat16BitsArray(this);
  428. return wrap((function* () {
  429. // eslint-disable-next-line no-restricted-syntax
  430. for (const [i, val] of TypedArrayPrototypeEntries(float16bitsArray)) {
  431. yield /** @type {[Number, number]} */ ([i, convertToNumber(val)]);
  432. }
  433. })());
  434. }
  435. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.at */
  436. at(index) {
  437. assertFloat16Array(this);
  438. const float16bitsArray = getFloat16BitsArray(this);
  439. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  440. const relativeIndex = ToIntegerOrInfinity(index);
  441. const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
  442. if (k < 0 || k >= length) {
  443. return;
  444. }
  445. return convertToNumber(float16bitsArray[k]);
  446. }
  447. /** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with */
  448. with(index, value) {
  449. assertFloat16Array(this);
  450. const float16bitsArray = getFloat16BitsArray(this);
  451. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  452. const relativeIndex = ToIntegerOrInfinity(index);
  453. const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
  454. const number = +value;
  455. if (k < 0 || k >= length) {
  456. throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
  457. }
  458. // don't use SpeciesConstructor
  459. const uint16 = new NativeUint16Array(
  460. TypedArrayPrototypeGetBuffer(float16bitsArray),
  461. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  462. TypedArrayPrototypeGetLength(float16bitsArray)
  463. );
  464. const cloned = new Float16Array(
  465. TypedArrayPrototypeGetBuffer(
  466. TypedArrayPrototypeSlice(uint16)
  467. )
  468. );
  469. const array = getFloat16BitsArray(cloned);
  470. array[k] = roundToFloat16Bits(number);
  471. return cloned;
  472. }
  473. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.map */
  474. map(callback, ...opts) {
  475. assertFloat16Array(this);
  476. const float16bitsArray = getFloat16BitsArray(this);
  477. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  478. const thisArg = opts[0];
  479. const Constructor = SpeciesConstructor(float16bitsArray, Float16Array);
  480. // for optimization
  481. if (Constructor === Float16Array) {
  482. const proxy = new Float16Array(length);
  483. const array = getFloat16BitsArray(proxy);
  484. for (let i = 0; i < length; ++i) {
  485. const val = convertToNumber(float16bitsArray[i]);
  486. array[i] = roundToFloat16Bits(
  487. ReflectApply(callback, thisArg, [val, i, this])
  488. );
  489. }
  490. return proxy;
  491. }
  492. const array = new Constructor(length);
  493. assertSpeciesTypedArray(array, length);
  494. for (let i = 0; i < length; ++i) {
  495. const val = convertToNumber(float16bitsArray[i]);
  496. array[i] = ReflectApply(callback, thisArg, [val, i, this]);
  497. }
  498. return /** @type {any} */ (array);
  499. }
  500. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.filter */
  501. filter(callback, ...opts) {
  502. assertFloat16Array(this);
  503. const float16bitsArray = getFloat16BitsArray(this);
  504. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  505. const thisArg = opts[0];
  506. const kept = [];
  507. for (let i = 0; i < length; ++i) {
  508. const val = convertToNumber(float16bitsArray[i]);
  509. if (ReflectApply(callback, thisArg, [val, i, this])) {
  510. ArrayPrototypePush(kept, val);
  511. }
  512. }
  513. const Constructor = SpeciesConstructor(float16bitsArray, Float16Array);
  514. const array = new Constructor(kept);
  515. assertSpeciesTypedArray(array);
  516. return /** @type {any} */ (array);
  517. }
  518. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce */
  519. reduce(callback, ...opts) {
  520. assertFloat16Array(this);
  521. const float16bitsArray = getFloat16BitsArray(this);
  522. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  523. if (length === 0 && opts.length === 0) {
  524. throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
  525. }
  526. let accumulator, start;
  527. if (opts.length === 0) {
  528. accumulator = convertToNumber(float16bitsArray[0]);
  529. start = 1;
  530. } else {
  531. accumulator = opts[0];
  532. start = 0;
  533. }
  534. for (let i = start; i < length; ++i) {
  535. accumulator = callback(
  536. accumulator,
  537. convertToNumber(float16bitsArray[i]),
  538. i,
  539. this
  540. );
  541. }
  542. return accumulator;
  543. }
  544. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduceright */
  545. reduceRight(callback, ...opts) {
  546. assertFloat16Array(this);
  547. const float16bitsArray = getFloat16BitsArray(this);
  548. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  549. if (length === 0 && opts.length === 0) {
  550. throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
  551. }
  552. let accumulator, start;
  553. if (opts.length === 0) {
  554. accumulator = convertToNumber(float16bitsArray[length - 1]);
  555. start = length - 2;
  556. } else {
  557. accumulator = opts[0];
  558. start = length - 1;
  559. }
  560. for (let i = start; i >= 0; --i) {
  561. accumulator = callback(
  562. accumulator,
  563. convertToNumber(float16bitsArray[i]),
  564. i,
  565. this
  566. );
  567. }
  568. return accumulator;
  569. }
  570. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.foreach */
  571. forEach(callback, ...opts) {
  572. assertFloat16Array(this);
  573. const float16bitsArray = getFloat16BitsArray(this);
  574. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  575. const thisArg = opts[0];
  576. for (let i = 0; i < length; ++i) {
  577. ReflectApply(callback, thisArg, [
  578. convertToNumber(float16bitsArray[i]),
  579. i,
  580. this,
  581. ]);
  582. }
  583. }
  584. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.find */
  585. find(callback, ...opts) {
  586. assertFloat16Array(this);
  587. const float16bitsArray = getFloat16BitsArray(this);
  588. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  589. const thisArg = opts[0];
  590. for (let i = 0; i < length; ++i) {
  591. const value = convertToNumber(float16bitsArray[i]);
  592. if (ReflectApply(callback, thisArg, [value, i, this])) {
  593. return value;
  594. }
  595. }
  596. }
  597. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.findindex */
  598. findIndex(callback, ...opts) {
  599. assertFloat16Array(this);
  600. const float16bitsArray = getFloat16BitsArray(this);
  601. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  602. const thisArg = opts[0];
  603. for (let i = 0; i < length; ++i) {
  604. const value = convertToNumber(float16bitsArray[i]);
  605. if (ReflectApply(callback, thisArg, [value, i, this])) {
  606. return i;
  607. }
  608. }
  609. return -1;
  610. }
  611. /** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast */
  612. findLast(callback, ...opts) {
  613. assertFloat16Array(this);
  614. const float16bitsArray = getFloat16BitsArray(this);
  615. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  616. const thisArg = opts[0];
  617. for (let i = length - 1; i >= 0; --i) {
  618. const value = convertToNumber(float16bitsArray[i]);
  619. if (ReflectApply(callback, thisArg, [value, i, this])) {
  620. return value;
  621. }
  622. }
  623. }
  624. /** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex */
  625. findLastIndex(callback, ...opts) {
  626. assertFloat16Array(this);
  627. const float16bitsArray = getFloat16BitsArray(this);
  628. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  629. const thisArg = opts[0];
  630. for (let i = length - 1; i >= 0; --i) {
  631. const value = convertToNumber(float16bitsArray[i]);
  632. if (ReflectApply(callback, thisArg, [value, i, this])) {
  633. return i;
  634. }
  635. }
  636. return -1;
  637. }
  638. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.every */
  639. every(callback, ...opts) {
  640. assertFloat16Array(this);
  641. const float16bitsArray = getFloat16BitsArray(this);
  642. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  643. const thisArg = opts[0];
  644. for (let i = 0; i < length; ++i) {
  645. if (
  646. !ReflectApply(callback, thisArg, [
  647. convertToNumber(float16bitsArray[i]),
  648. i,
  649. this,
  650. ])
  651. ) {
  652. return false;
  653. }
  654. }
  655. return true;
  656. }
  657. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.some */
  658. some(callback, ...opts) {
  659. assertFloat16Array(this);
  660. const float16bitsArray = getFloat16BitsArray(this);
  661. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  662. const thisArg = opts[0];
  663. for (let i = 0; i < length; ++i) {
  664. if (
  665. ReflectApply(callback, thisArg, [
  666. convertToNumber(float16bitsArray[i]),
  667. i,
  668. this,
  669. ])
  670. ) {
  671. return true;
  672. }
  673. }
  674. return false;
  675. }
  676. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.set */
  677. set(input, ...opts) {
  678. assertFloat16Array(this);
  679. const float16bitsArray = getFloat16BitsArray(this);
  680. const targetOffset = ToIntegerOrInfinity(opts[0]);
  681. if (targetOffset < 0) {
  682. throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
  683. }
  684. if (input == null) {
  685. throw NativeTypeError(
  686. CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
  687. );
  688. }
  689. if (isNativeBigIntTypedArray(input)) {
  690. throw NativeTypeError(
  691. CANNOT_MIX_BIGINT_AND_OTHER_TYPES
  692. );
  693. }
  694. // for optimization
  695. if (isFloat16Array(input)) {
  696. // peel off Proxy
  697. return TypedArrayPrototypeSet(
  698. getFloat16BitsArray(this),
  699. getFloat16BitsArray(input),
  700. targetOffset
  701. );
  702. }
  703. if (isNativeTypedArray(input)) {
  704. const buffer = TypedArrayPrototypeGetBuffer(input);
  705. if (IsDetachedBuffer(buffer)) {
  706. throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
  707. }
  708. }
  709. const targetLength = TypedArrayPrototypeGetLength(float16bitsArray);
  710. const src = NativeObject(input);
  711. const srcLength = ToLength(src.length);
  712. if (targetOffset === Infinity || srcLength + targetOffset > targetLength) {
  713. throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
  714. }
  715. for (let i = 0; i < srcLength; ++i) {
  716. float16bitsArray[i + targetOffset] = roundToFloat16Bits(src[i]);
  717. }
  718. }
  719. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reverse */
  720. reverse() {
  721. assertFloat16Array(this);
  722. const float16bitsArray = getFloat16BitsArray(this);
  723. TypedArrayPrototypeReverse(float16bitsArray);
  724. return this;
  725. }
  726. /** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toReversed */
  727. toReversed() {
  728. assertFloat16Array(this);
  729. const float16bitsArray = getFloat16BitsArray(this);
  730. // don't use SpeciesConstructor
  731. const uint16 = new NativeUint16Array(
  732. TypedArrayPrototypeGetBuffer(float16bitsArray),
  733. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  734. TypedArrayPrototypeGetLength(float16bitsArray)
  735. );
  736. const cloned = new Float16Array(
  737. TypedArrayPrototypeGetBuffer(
  738. TypedArrayPrototypeSlice(uint16)
  739. )
  740. );
  741. const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
  742. TypedArrayPrototypeReverse(clonedFloat16bitsArray);
  743. return cloned;
  744. }
  745. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill */
  746. fill(value, ...opts) {
  747. assertFloat16Array(this);
  748. const float16bitsArray = getFloat16BitsArray(this);
  749. TypedArrayPrototypeFill(
  750. float16bitsArray,
  751. roundToFloat16Bits(value),
  752. ...safeIfNeeded(opts)
  753. );
  754. return this;
  755. }
  756. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin */
  757. copyWithin(target, start, ...opts) {
  758. assertFloat16Array(this);
  759. const float16bitsArray = getFloat16BitsArray(this);
  760. TypedArrayPrototypeCopyWithin(float16bitsArray, target, start, ...safeIfNeeded(opts));
  761. return this;
  762. }
  763. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort */
  764. sort(compareFn) {
  765. assertFloat16Array(this);
  766. const float16bitsArray = getFloat16BitsArray(this);
  767. const sortCompare = compareFn !== undefined ? compareFn : defaultCompare;
  768. TypedArrayPrototypeSort(float16bitsArray, (x, y) => {
  769. return sortCompare(convertToNumber(x), convertToNumber(y));
  770. });
  771. return this;
  772. }
  773. /** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSorted */
  774. toSorted(compareFn) {
  775. assertFloat16Array(this);
  776. const float16bitsArray = getFloat16BitsArray(this);
  777. if (compareFn !== undefined && typeof compareFn !== "function") {
  778. throw new NativeTypeError(THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED);
  779. }
  780. const sortCompare = compareFn !== undefined ? compareFn : defaultCompare;
  781. // don't use SpeciesConstructor
  782. const uint16 = new NativeUint16Array(
  783. TypedArrayPrototypeGetBuffer(float16bitsArray),
  784. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  785. TypedArrayPrototypeGetLength(float16bitsArray)
  786. );
  787. const cloned = new Float16Array(
  788. TypedArrayPrototypeGetBuffer(
  789. TypedArrayPrototypeSlice(uint16)
  790. )
  791. );
  792. const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
  793. TypedArrayPrototypeSort(clonedFloat16bitsArray, (x, y) => {
  794. return sortCompare(convertToNumber(x), convertToNumber(y));
  795. });
  796. return cloned;
  797. }
  798. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.slice */
  799. slice(start, end) {
  800. assertFloat16Array(this);
  801. const float16bitsArray = getFloat16BitsArray(this);
  802. const Constructor = SpeciesConstructor(float16bitsArray, Float16Array);
  803. // for optimization
  804. if (Constructor === Float16Array) {
  805. const uint16 = new NativeUint16Array(
  806. TypedArrayPrototypeGetBuffer(float16bitsArray),
  807. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  808. TypedArrayPrototypeGetLength(float16bitsArray)
  809. );
  810. return new Float16Array(
  811. TypedArrayPrototypeGetBuffer(
  812. TypedArrayPrototypeSlice(uint16, start, end)
  813. )
  814. );
  815. }
  816. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  817. const relativeStart = ToIntegerOrInfinity(start);
  818. const relativeEnd = end === undefined ? length : ToIntegerOrInfinity(end);
  819. let k;
  820. if (relativeStart === -Infinity) {
  821. k = 0;
  822. } else if (relativeStart < 0) {
  823. k = length + relativeStart > 0 ? length + relativeStart : 0;
  824. } else {
  825. k = length < relativeStart ? length : relativeStart;
  826. }
  827. let final;
  828. if (relativeEnd === -Infinity) {
  829. final = 0;
  830. } else if (relativeEnd < 0) {
  831. final = length + relativeEnd > 0 ? length + relativeEnd : 0;
  832. } else {
  833. final = length < relativeEnd ? length : relativeEnd;
  834. }
  835. const count = final - k > 0 ? final - k : 0;
  836. const array = new Constructor(count);
  837. assertSpeciesTypedArray(array, count);
  838. if (count === 0) {
  839. return array;
  840. }
  841. const buffer = TypedArrayPrototypeGetBuffer(float16bitsArray);
  842. if (IsDetachedBuffer(buffer)) {
  843. throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
  844. }
  845. let n = 0;
  846. while (k < final) {
  847. array[n] = convertToNumber(float16bitsArray[k]);
  848. ++k;
  849. ++n;
  850. }
  851. return /** @type {any} */ (array);
  852. }
  853. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray */
  854. subarray(begin, end) {
  855. assertFloat16Array(this);
  856. const float16bitsArray = getFloat16BitsArray(this);
  857. const Constructor = SpeciesConstructor(float16bitsArray, Float16Array);
  858. const uint16 = new NativeUint16Array(
  859. TypedArrayPrototypeGetBuffer(float16bitsArray),
  860. TypedArrayPrototypeGetByteOffset(float16bitsArray),
  861. TypedArrayPrototypeGetLength(float16bitsArray)
  862. );
  863. const uint16Subarray = TypedArrayPrototypeSubarray(uint16, begin, end);
  864. const array = new Constructor(
  865. TypedArrayPrototypeGetBuffer(uint16Subarray),
  866. TypedArrayPrototypeGetByteOffset(uint16Subarray),
  867. TypedArrayPrototypeGetLength(uint16Subarray)
  868. );
  869. assertSpeciesTypedArray(array);
  870. return /** @type {any} */ (array);
  871. }
  872. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.indexof */
  873. indexOf(element, ...opts) {
  874. assertFloat16Array(this);
  875. const float16bitsArray = getFloat16BitsArray(this);
  876. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  877. let from = ToIntegerOrInfinity(opts[0]);
  878. if (from === Infinity) {
  879. return -1;
  880. }
  881. if (from < 0) {
  882. from += length;
  883. if (from < 0) {
  884. from = 0;
  885. }
  886. }
  887. for (let i = from; i < length; ++i) {
  888. if (
  889. ObjectHasOwn(float16bitsArray, i) &&
  890. convertToNumber(float16bitsArray[i]) === element
  891. ) {
  892. return i;
  893. }
  894. }
  895. return -1;
  896. }
  897. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof */
  898. lastIndexOf(element, ...opts) {
  899. assertFloat16Array(this);
  900. const float16bitsArray = getFloat16BitsArray(this);
  901. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  902. let from = opts.length >= 1 ? ToIntegerOrInfinity(opts[0]) : length - 1;
  903. if (from === -Infinity) {
  904. return -1;
  905. }
  906. if (from >= 0) {
  907. from = from < length - 1 ? from : length - 1;
  908. } else {
  909. from += length;
  910. }
  911. for (let i = from; i >= 0; --i) {
  912. if (
  913. ObjectHasOwn(float16bitsArray, i) &&
  914. convertToNumber(float16bitsArray[i]) === element
  915. ) {
  916. return i;
  917. }
  918. }
  919. return -1;
  920. }
  921. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes */
  922. includes(element, ...opts) {
  923. assertFloat16Array(this);
  924. const float16bitsArray = getFloat16BitsArray(this);
  925. const length = TypedArrayPrototypeGetLength(float16bitsArray);
  926. let from = ToIntegerOrInfinity(opts[0]);
  927. if (from === Infinity) {
  928. return false;
  929. }
  930. if (from < 0) {
  931. from += length;
  932. if (from < 0) {
  933. from = 0;
  934. }
  935. }
  936. const isNaN = NumberIsNaN(element);
  937. for (let i = from; i < length; ++i) {
  938. const value = convertToNumber(float16bitsArray[i]);
  939. if (isNaN && NumberIsNaN(value)) {
  940. return true;
  941. }
  942. if (value === element) {
  943. return true;
  944. }
  945. }
  946. return false;
  947. }
  948. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.join */
  949. join(separator) {
  950. assertFloat16Array(this);
  951. const float16bitsArray = getFloat16BitsArray(this);
  952. const array = copyToArray(float16bitsArray);
  953. return ArrayPrototypeJoin(array, separator);
  954. }
  955. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.tolocalestring */
  956. toLocaleString(...opts) {
  957. assertFloat16Array(this);
  958. const float16bitsArray = getFloat16BitsArray(this);
  959. const array = copyToArray(float16bitsArray);
  960. return ArrayPrototypeToLocaleString(array, ...safeIfNeeded(opts));
  961. }
  962. /** @see https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag */
  963. get [SymbolToStringTag]() {
  964. if (isFloat16Array(this)) {
  965. return /** @type {any} */ ("Float16Array");
  966. }
  967. }
  968. }
  969. /** @see https://tc39.es/ecma262/#sec-typedarray.bytes_per_element */
  970. ObjectDefineProperty(Float16Array, "BYTES_PER_ELEMENT", {
  971. value: BYTES_PER_ELEMENT,
  972. });
  973. // limitation: It is peaked by `Object.getOwnPropertySymbols(Float16Array)` and `Reflect.ownKeys(Float16Array)`
  974. ObjectDefineProperty(Float16Array, brand, {});
  975. /** @see https://tc39.es/ecma262/#sec-properties-of-the-typedarray-constructors */
  976. ReflectSetPrototypeOf(Float16Array, TypedArray);
  977. const Float16ArrayPrototype = Float16Array.prototype;
  978. /** @see https://tc39.es/ecma262/#sec-typedarray.prototype.bytes_per_element */
  979. ObjectDefineProperty(Float16ArrayPrototype, "BYTES_PER_ELEMENT", {
  980. value: BYTES_PER_ELEMENT,
  981. });
  982. /** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype-@@iterator */
  983. ObjectDefineProperty(Float16ArrayPrototype, SymbolIterator, {
  984. value: Float16ArrayPrototype.values,
  985. writable: true,
  986. configurable: true,
  987. });
  988. ReflectSetPrototypeOf(Float16ArrayPrototype, TypedArrayPrototype);