jseption 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +30 -6
  2. package/dist/atoms.d.ts +1 -0
  3. package/dist/atoms.js +2 -1
  4. package/dist/atoms.js.map +1 -1
  5. package/dist/builtins/base64.d.ts +14 -0
  6. package/dist/builtins/base64.js +219 -0
  7. package/dist/builtins/base64.js.map +1 -0
  8. package/dist/builtins/bigint.js +3 -3
  9. package/dist/builtins/bigint.js.map +1 -1
  10. package/dist/builtins/date.d.ts +1 -0
  11. package/dist/builtins/date.js +26 -12
  12. package/dist/builtins/date.js.map +1 -1
  13. package/dist/builtins/error.js +9 -0
  14. package/dist/builtins/error.js.map +1 -1
  15. package/dist/builtins/float16.d.ts +3 -0
  16. package/dist/builtins/float16.js +69 -0
  17. package/dist/builtins/float16.js.map +1 -0
  18. package/dist/builtins/function.js +2 -2
  19. package/dist/builtins/index.js +9 -6
  20. package/dist/builtins/index.js.map +1 -1
  21. package/dist/builtins/iterator.d.ts +2 -0
  22. package/dist/builtins/iterator.js +624 -0
  23. package/dist/builtins/iterator.js.map +1 -0
  24. package/dist/builtins/json.d.ts +13 -1
  25. package/dist/builtins/json.js +283 -211
  26. package/dist/builtins/json.js.map +1 -1
  27. package/dist/builtins/mapset.js +365 -6
  28. package/dist/builtins/mapset.js.map +1 -1
  29. package/dist/builtins/math.js +203 -3
  30. package/dist/builtins/math.js.map +1 -1
  31. package/dist/builtins/native.js +6 -6
  32. package/dist/builtins/object.js +9 -2
  33. package/dist/builtins/object.js.map +1 -1
  34. package/dist/builtins/promise.js +31 -11
  35. package/dist/builtins/promise.js.map +1 -1
  36. package/dist/builtins/proxy.js +2 -2
  37. package/dist/builtins/reflect.js +6 -2
  38. package/dist/builtins/reflect.js.map +1 -1
  39. package/dist/builtins/regexp.js +74 -3
  40. package/dist/builtins/regexp.js.map +1 -1
  41. package/dist/builtins/string.js +1 -1
  42. package/dist/builtins/symbol.js +1 -1
  43. package/dist/builtins/symbol.js.map +1 -1
  44. package/dist/builtins/typedarray.d.ts +4 -1
  45. package/dist/builtins/typedarray.js +325 -37
  46. package/dist/builtins/typedarray.js.map +1 -1
  47. package/dist/builtins/weakref.js +7 -7
  48. package/dist/embed.d.ts +5 -0
  49. package/dist/embed.js +36 -11
  50. package/dist/embed.js.map +1 -1
  51. package/dist/interpreter.js +15 -14
  52. package/dist/interpreter.js.map +1 -1
  53. package/dist/jit.d.ts +1 -0
  54. package/dist/jit.js +51 -13
  55. package/dist/jit.js.map +1 -1
  56. package/dist/jit_hook.d.ts +1 -0
  57. package/dist/jit_hook.js.map +1 -1
  58. package/dist/jit_runtime.d.ts +1 -1
  59. package/dist/jit_runtime.js +6 -6
  60. package/dist/jit_runtime.js.map +1 -1
  61. package/dist/jit_stack.d.ts +1 -0
  62. package/dist/jit_stack.js +2 -1
  63. package/dist/jit_stack.js.map +1 -1
  64. package/dist/jseption.d.ts +2 -0
  65. package/dist/jseption.js +1 -0
  66. package/dist/jseption.js.map +1 -1
  67. package/dist/membrane.d.ts +6 -0
  68. package/dist/membrane.js +7 -3
  69. package/dist/membrane.js.map +1 -1
  70. package/dist/module.js +5 -3
  71. package/dist/module.js.map +1 -1
  72. package/dist/parser.js +26 -9
  73. package/dist/parser.js.map +1 -1
  74. package/dist/print.d.ts +12 -0
  75. package/dist/print.js +494 -0
  76. package/dist/print.js.map +1 -0
  77. package/dist/qjs.js +13 -10
  78. package/dist/qjs.js.map +1 -1
  79. package/dist/quickjs.d.ts +8 -0
  80. package/dist/quickjs.js +132 -53
  81. package/dist/quickjs.js.map +1 -1
  82. package/dist/std.d.ts +4 -2
  83. package/dist/std.js +42 -8
  84. package/dist/std.js.map +1 -1
  85. package/dist/values.d.ts +31 -27
  86. package/dist/values.js.map +1 -1
  87. package/dist/version.d.ts +1 -1
  88. package/dist/version.js +1 -1
  89. package/dist/version.js.map +1 -1
  90. package/package.json +1 -1
@@ -8,42 +8,57 @@
8
8
  * access goes through host typed array / DataView views created over it.
9
9
  */
10
10
  import * as Q from "../quickjs.js";
11
- import { JS_EXCEPTION, JS_IsException, JS_IsUndefined, JS_IsObject, JS_IsNull, JSArrayBuffer, JSTypedArray, JS_NewObject, JS_NewObjectProto, JS_NewArray, JS_NewCFunction2, JS_NewCFunction3, JS_DefinePropertyValue, JS_DefinePropertyValueStr, JS_DefinePropertyValueInt64, JS_PROP_WRITABLE, JS_PROP_CONFIGURABLE, JS_PROP_C_W_E, JS_PROP_THROW, JS_GetProperty, JS_GetPropertyInt64, JS_SetPropertyInt64, JS_GetPropertyUint32, JS_SetPropertyUint32, JS_GetPropertyValue, JS_SetPropertyValue, JS_ToString, JS_ToBoolFree, JS_ToFloat64, JS_ToUint32Free, JS_ToUint8ClampFree, JS_ToBigInt64, JS_ToIndex, JS_ToInt64Sat, JS_ToInt32Clamp, JS_ToInt64Clamp, JS_ToLengthFree, JS_ToPrimitive, HINT_NUMBER, JS_ToObject, js_get_length64, JS_ThrowTypeError, JS_ThrowRangeError, JS_ThrowTypeErrorInvalidClass, JS_IsFunction, JS_Call, JS_CallConstructor, JS_Invoke, js_create_from_ctor, js_same_value, JS_GetIterator2, JS_IteratorNext, JS_CreateDataPropertyUint32, JS_GetOpaque2, JS_AtomToString, JS_SetPropertyFunctionList, JS_NewGlobalCConstructorOnly, JS_NewGlobalCConstructor2, JS_SetConstructor, JS_CFUNC_DEF, JS_CFUNC_MAGIC_DEF, JS_NATIVE_DEF, JS_CGETSET_DEF, JS_CGETSET_MAGIC_DEF, JS_ALIAS_DEF, JS_PROP_STRING_DEF, JS_ATOM_length, JS_ATOM_toString, JS_ATOM_toLocaleString, JS_ATOM_join, JS_ATOM_next, JS_ATOM_set, JS_ATOM_Symbol_iterator, JS_ATOM_Symbol_species, JS_ATOM_Symbol_toStringTag, JS_ATOM_Uint8ClampedArray, } from "../quickjs.js";
11
+ import { JS_EXCEPTION, JS_IsException, JS_IsUndefined, JS_IsObject, JS_IsNull, JSArrayBuffer, JSTypedArray, JS_NewObject, JS_NewObjectProto, JS_NewArray, JS_NewCFunction2, JS_NewCFunction3, JS_DefinePropertyValue, JS_DefinePropertyValueStr, JS_DefinePropertyValueInt64, JS_PROP_WRITABLE, JS_PROP_CONFIGURABLE, JS_PROP_C_W_E, JS_PROP_THROW, JS_GetProperty, JS_GetPropertyInt64, JS_SetPropertyInt64, JS_GetPropertyUint32, JS_SetPropertyUint32, JS_GetPropertyValue, JS_SetPropertyValue, JS_ToString, JS_ToBoolFree, JS_ToFloat64, JS_ToUint32Free, JS_ToUint8ClampFree, JS_ToBigInt64, JS_ToIndex, JS_ToInt64Sat, JS_ToInt32Clamp, JS_ToInt64Clamp, JS_ToLengthFree, JS_ToPrimitive, HINT_NUMBER, JS_ToObject, js_get_length64, JS_ThrowTypeError, JS_ThrowRangeError, JS_ThrowSyntaxError, JS_GetPropertyStr, JS_ThrowTypeErrorInvalidClass, JS_IsFunction, JS_Call, JS_CallConstructor, JS_Invoke, js_create_from_ctor, js_same_value, JS_GetIterator2, JS_IteratorNext, JS_CreateDataPropertyUint32, JS_GetOpaque2, JS_AtomToString, JS_SetPropertyFunctionList, JS_NewGlobalCConstructorOnly, JS_NewGlobalCConstructor2, JS_SetConstructor, JS_CFUNC_DEF, JS_CFUNC_MAGIC_DEF, JS_NATIVE_DEF, JS_CGETSET_DEF, JS_CGETSET_MAGIC_DEF, JS_ALIAS_DEF, JS_PROP_STRING_DEF, JS_ATOM_length, JS_ATOM_toString, JS_ATOM_toLocaleString, JS_ATOM_join, JS_ATOM_next, JS_ATOM_set, JS_ATOM_Symbol_iterator, JS_ATOM_Symbol_species, JS_ATOM_Symbol_toStringTag, JS_ATOM_Uint8ClampedArray, } from "../quickjs.js";
12
12
  import { JS_SpeciesConstructor, check_function } from "./promise.js";
13
13
  import { fix_array_iterator } from "./native.js";
14
+ import { tofp16, fromfp16, f16round } from "./float16.js";
15
+ import { B64_ALPHABET_BASE64, B64_ALPHABET_BASE64URL, B64_LAST_LOOSE, B64_LAST_STRICT, B64_LAST_STOP_BEFORE_PARTIAL, b64_encode, from_base64, u8a_hex_encode, u8a_hex_decode, } from "./base64.js";
14
16
  const HOST_TYPED_ARRAY_PROTO = Object.getPrototypeOf(Uint8Array.prototype);
15
17
  /* JS_ITERATOR_KIND_xxx (same values as JSIteratorKind in index.ts) */
16
18
  const JS_ITERATOR_KIND_KEY = 0;
17
19
  const JS_ITERATOR_KIND_VALUE = 1;
18
20
  const JS_ITERATOR_KIND_KEY_AND_VALUE = 2;
19
- const JS_TYPED_ARRAY_COUNT = 31 /* JSClassID.FLOAT64_ARRAY */ - 21 /* JSClassID.UINT8C_ARRAY */ + 1;
21
+ const JS_TYPED_ARRAY_COUNT = 32 /* JSClassID.FLOAT64_ARRAY */ - 21 /* JSClassID.UINT8C_ARRAY */ + 1;
20
22
  const typed_array_size_log2_tab = [
21
23
  0, 0, 0, 1, 1, 2, 2,
22
24
  3, 3, /* BigInt64Array, BigUint64Array */
23
- 2, 3,
25
+ 1, 2, 3, /* Float16Array, Float32Array, Float64Array */
24
26
  ];
25
27
  function typed_array_size_log2(class_id) {
26
28
  return typed_array_size_log2_tab[class_id - 21 /* JSClassID.UINT8C_ARRAY */];
27
29
  }
30
+ /* Guest typed arrays are host typed arrays, so Float16Array exists in the
31
+ guest only when the host has it (its class slot stays empty otherwise).
32
+ Math.f16round and DataView's float16 methods do not need it. */
33
+ const HostFloat16Array = globalThis.Float16Array;
28
34
  const host_ta_ctors = [
29
35
  Uint8ClampedArray, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array,
30
- BigInt64Array, BigUint64Array, Float32Array, Float64Array,
36
+ BigInt64Array, BigUint64Array, HostFloat16Array, Float32Array, Float64Array,
31
37
  ];
38
+ /* true if the host provides the guest typed array class 'class_id' */
39
+ export function typed_array_class_available(class_id) {
40
+ return host_ta_ctors[class_id - 21 /* JSClassID.UINT8C_ARRAY */] !== undefined;
41
+ }
32
42
  /* ---------------------------------------------------------------------
33
43
  ArrayBuffer
34
44
  --------------------------------------------------------------------- */
35
45
  /* array buffer data with the resizable extension. The host buffer is
36
46
  resizable (growable when shared) when max_len >= 0; 'data' is a length
37
- tracking view over it. */
47
+ tracking view over it. With 'existing', the guest buffer is that host
48
+ buffer itself (JS_NewArrayBufferFrom): the two sides share the bytes. */
38
49
  export class JSArrayBufferData extends JSArrayBuffer {
39
50
  /* maximum byte length for resizable buffers, -1 otherwise */
40
51
  max_byte_length = -1;
41
52
  /* cached host DataView over 'data' */
42
53
  dv = null;
43
54
  dv_data = null;
44
- constructor(len, shared, max_len) {
55
+ constructor(len, shared, max_len, existing) {
45
56
  let buffer;
46
- if (shared)
57
+ if (existing) {
58
+ buffer = existing;
59
+ max_len = (shared ? existing.growable : existing.resizable) ? existing.maxByteLength : -1;
60
+ }
61
+ else if (shared)
47
62
  buffer = max_len >= 0 ? new SharedArrayBuffer(len, { maxByteLength: max_len }) : new SharedArrayBuffer(len);
48
63
  else
49
64
  buffer = max_len >= 0 ? new ArrayBuffer(len, { maxByteLength: max_len }) : new ArrayBuffer(len);
@@ -51,6 +66,10 @@ export class JSArrayBufferData extends JSArrayBuffer {
51
66
  this.max_byte_length = max_len;
52
67
  }
53
68
  }
69
+ /* a host SharedArrayBuffer, where the host has one */
70
+ export function isSharedArrayBuffer(v) {
71
+ return typeof SharedArrayBuffer === 'function' && v instanceof SharedArrayBuffer;
72
+ }
54
73
  function array_buffer_get_dv(abuf) {
55
74
  const a = abuf;
56
75
  if (a.dv === null || a.dv_data !== abuf.data) {
@@ -77,7 +96,7 @@ function JS_ThrowTypeErrorArrayBufferOOB(ctx) {
77
96
  }
78
97
  /* XXX: we are currently limited to 2 GB */
79
98
  const ARRAY_BUFFER_MAX_LENGTH = 0x7fffffff;
80
- function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, buf) {
99
+ function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, buf, existing) {
81
100
  const obj = js_create_from_ctor(ctx, new_target, class_id);
82
101
  if (JS_IsException(obj))
83
102
  return obj;
@@ -85,12 +104,21 @@ function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, b
85
104
  return JS_ThrowRangeError(ctx, 'invalid array buffer length');
86
105
  if (max_len > ARRAY_BUFFER_MAX_LENGTH)
87
106
  return JS_ThrowRangeError(ctx, 'invalid array buffer maximum length');
88
- const abuf = new JSArrayBufferData(len, class_id === 20 /* JSClassID.SHARED_ARRAY_BUFFER */, max_len);
107
+ const abuf = new JSArrayBufferData(len, class_id === 20 /* JSClassID.SHARED_ARRAY_BUFFER */, max_len, existing);
89
108
  if (buf)
90
109
  abuf.data.set(buf.subarray(0, len));
91
110
  Q.JS_SetOpaque(obj, abuf);
92
111
  return obj;
93
112
  }
113
+ /* a guest ArrayBuffer (or SharedArrayBuffer) over the host buffer itself, not a
114
+ copy: what the guest writes the host sees, and the other way round. A
115
+ buffer is bytes: it reaches no host object, so sharing it keeps the
116
+ sandbox rules (its guest prototype is the guest's). The guest cannot
117
+ detach, resize or transfer it beyond what the host buffer allows. */
118
+ export function JS_NewArrayBufferFrom(ctx, buffer) {
119
+ const shared = isSharedArrayBuffer(buffer);
120
+ return js_array_buffer_constructor3(ctx, undefined, buffer.byteLength, -1, shared ? 20 /* JSClassID.SHARED_ARRAY_BUFFER */ : 19 /* JSClassID.ARRAY_BUFFER */, null, buffer);
121
+ }
94
122
  function js_array_buffer_constructor2(ctx, new_target, len, class_id) {
95
123
  return js_array_buffer_constructor3(ctx, new_target, len, -1, class_id, null);
96
124
  }
@@ -116,7 +144,7 @@ function js_array_buffer_constructor0(ctx, new_target, argv, class_id) {
116
144
  if (max_len < 0)
117
145
  return JS_EXCEPTION;
118
146
  if (len > max_len)
119
- return JS_ThrowRangeError(ctx, 'invalid array buffer length');
147
+ return JS_ThrowRangeError(ctx, 'invalid array buffer max length');
120
148
  }
121
149
  }
122
150
  return js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, null);
@@ -130,7 +158,7 @@ function js_shared_array_buffer_constructor(ctx, new_target, argv) {
130
158
  }
131
159
  function js_array_buffer_isView(ctx, this_val, argv) {
132
160
  const v = argv[0];
133
- return Q.JS_IsObject(v) && Q.JS_GetClassID(v) >= 21 /* JSClassID.UINT8C_ARRAY */ && Q.JS_GetClassID(v) <= 32 /* JSClassID.DATAVIEW */;
161
+ return Q.JS_IsObject(v) && Q.JS_GetClassID(v) >= 21 /* JSClassID.UINT8C_ARRAY */ && Q.JS_GetClassID(v) <= 33 /* JSClassID.DATAVIEW */;
134
162
  }
135
163
  function js_get_this(ctx, this_val) { return this_val; }
136
164
  const js_array_buffer_funcs = [
@@ -316,12 +344,12 @@ const js_shared_array_buffer_proto_funcs = [
316
344
  Typed arrays
317
345
  --------------------------------------------------------------------- */
318
346
  export function is_typed_array_class(class_id) {
319
- return class_id >= 21 /* JSClassID.UINT8C_ARRAY */ && class_id <= 31 /* JSClassID.FLOAT64_ARRAY */;
347
+ return class_id >= 21 /* JSClassID.UINT8C_ARRAY */ && class_id <= 32 /* JSClassID.FLOAT64_ARRAY */;
320
348
  }
321
349
  function get_typed_array(ctx, this_val, is_dataview) {
322
350
  if (Q.JS_IsObject(this_val)) {
323
351
  if (is_dataview) {
324
- if (Q.JS_GetClassID(this_val) === 32 /* JSClassID.DATAVIEW */)
352
+ if (Q.JS_GetClassID(this_val) === 33 /* JSClassID.DATAVIEW */)
325
353
  return this_val;
326
354
  }
327
355
  else {
@@ -357,7 +385,7 @@ function typed_array_get_byte_length(ta, size_log2) {
357
385
  }
358
386
  /* byte length of a typed array or DataView object (-1 if detached/OOB) */
359
387
  function js_typed_array_byte_length(p) {
360
- const size_log2 = Q.JS_GetClassID(p) === 32 /* JSClassID.DATAVIEW */ ? 0 : typed_array_size_log2(Q.JS_GetClassID(p));
388
+ const size_log2 = Q.JS_GetClassID(p) === 33 /* JSClassID.DATAVIEW */ ? 0 : typed_array_size_log2(Q.JS_GetClassID(p));
361
389
  return typed_array_get_byte_length(Q.JS_GetAnyOpaque(p), size_log2);
362
390
  }
363
391
  /* return true if the typed array is detached or out of bounds (resized buffer) */
@@ -951,7 +979,25 @@ function js_typed_array_indexOf(ctx, this_val, argv, special) {
951
979
  scan(d);
952
980
  break;
953
981
  }
954
- case 30 /* JSClassID.FLOAT32_ARRAY */:
982
+ case 30 /* JSClassID.FLOAT16_ARRAY */:
983
+ if (is_bigint)
984
+ break;
985
+ if (Number.isNaN(d)) {
986
+ /* special case: indexOf returns -1, includes finds NaN */
987
+ if (special !== special_includes)
988
+ return done();
989
+ for (; k !== stop; k += inc) {
990
+ if (Number.isNaN(view[k])) {
991
+ res = k;
992
+ break;
993
+ }
994
+ }
995
+ }
996
+ else if (f16round(d) === d) {
997
+ scan(d);
998
+ }
999
+ break;
1000
+ case 31 /* JSClassID.FLOAT32_ARRAY */:
955
1001
  if (is_bigint)
956
1002
  break;
957
1003
  if (Number.isNaN(d)) {
@@ -969,7 +1015,7 @@ function js_typed_array_indexOf(ctx, this_val, argv, special) {
969
1015
  scan(d);
970
1016
  }
971
1017
  break;
972
- case 31 /* JSClassID.FLOAT64_ARRAY */:
1018
+ case 32 /* JSClassID.FLOAT64_ARRAY */:
973
1019
  if (is_bigint)
974
1020
  break;
975
1021
  if (Number.isNaN(d)) {
@@ -1559,10 +1605,16 @@ function js_typed_array_constructor(ctx, new_target, argv, classid) {
1559
1605
  let len, offset;
1560
1606
  let track_rab = false;
1561
1607
  const arg0 = argv[0];
1608
+ /* the object (its prototype read from new.target) is created before the
1609
+ offset and the length are converted (QuickJS 68caa5f) */
1610
+ let obj;
1562
1611
  if (!Q.JS_IsObject(arg0)) {
1563
1612
  len = JS_ToIndex(ctx, arg0);
1564
1613
  if (len < 0)
1565
1614
  return JS_EXCEPTION;
1615
+ obj = js_create_from_ctor(ctx, new_target, classid);
1616
+ if (JS_IsException(obj))
1617
+ return JS_EXCEPTION;
1566
1618
  buffer = js_array_buffer_constructor1(ctx, undefined, len << size_log2);
1567
1619
  if (JS_IsException(buffer))
1568
1620
  return JS_EXCEPTION;
@@ -1571,15 +1623,20 @@ function js_typed_array_constructor(ctx, new_target, argv, classid) {
1571
1623
  else {
1572
1624
  const p = arg0;
1573
1625
  if (Q.JS_GetClassID(p) === 19 /* JSClassID.ARRAY_BUFFER */ || Q.JS_GetClassID(p) === 20 /* JSClassID.SHARED_ARRAY_BUFFER */) {
1626
+ obj = js_create_from_ctor(ctx, new_target, classid);
1627
+ if (JS_IsException(obj))
1628
+ return JS_EXCEPTION;
1574
1629
  const abuf = Q.JS_GetAnyOpaque(p);
1575
1630
  offset = JS_ToIndex(ctx, argv[1]);
1576
1631
  if (offset < 0)
1577
1632
  return JS_EXCEPTION;
1578
- if (abuf.detached)
1579
- return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
1580
- if ((offset & ((1 << size_log2) - 1)) !== 0 || offset > abuf.data.length)
1633
+ if ((offset & ((1 << size_log2) - 1)) !== 0)
1581
1634
  return JS_ThrowRangeError(ctx, 'invalid offset');
1582
1635
  if (JS_IsUndefined(argv[2])) {
1636
+ if (abuf.detached)
1637
+ return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
1638
+ if (offset > abuf.data.length)
1639
+ return JS_ThrowRangeError(ctx, 'invalid offset');
1583
1640
  if (array_buffer_is_resizable(abuf)) {
1584
1641
  track_rab = true;
1585
1642
  len = (abuf.data.length - offset) >> size_log2;
@@ -1610,9 +1667,6 @@ function js_typed_array_constructor(ctx, new_target, argv, classid) {
1610
1667
  }
1611
1668
  }
1612
1669
  }
1613
- const obj = js_create_from_ctor(ctx, new_target, classid);
1614
- if (JS_IsException(obj))
1615
- return JS_EXCEPTION;
1616
1670
  return typed_array_init(ctx, obj, buffer, offset, len, track_rab);
1617
1671
  }
1618
1672
  /* ---------------------------------------------------------------------
@@ -1635,6 +1689,7 @@ function js_dataview_constructor(ctx, new_target, argv) {
1635
1689
  return JS_ThrowRangeError(ctx, 'invalid byteOffset');
1636
1690
  let len = abuf.data.length - offset;
1637
1691
  let track_rab = false;
1692
+ let recompute_len = false;
1638
1693
  if (argv.length > 2 && !JS_IsUndefined(argv[2])) {
1639
1694
  const l = JS_ToIndex(ctx, argv[2]);
1640
1695
  if (l < 0)
@@ -1644,18 +1699,24 @@ function js_dataview_constructor(ctx, new_target, argv) {
1644
1699
  len = l;
1645
1700
  }
1646
1701
  else {
1702
+ recompute_len = true;
1647
1703
  track_rab = array_buffer_is_resizable(abuf);
1648
1704
  }
1649
- const obj = js_create_from_ctor(ctx, new_target, 32 /* JSClassID.DATAVIEW */);
1705
+ const obj = js_create_from_ctor(ctx, new_target, 33 /* JSClassID.DATAVIEW */);
1650
1706
  if (JS_IsException(obj))
1651
1707
  return JS_EXCEPTION;
1652
1708
  if (abuf.detached) {
1653
1709
  /* could have been detached in js_create_from_ctor() */
1654
1710
  return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
1655
1711
  }
1656
- /* the buffer could have been resized in js_create_from_ctor() */
1657
- if (offset > abuf.data.length || (!track_rab && offset + len > abuf.data.length))
1658
- return JS_ThrowTypeErrorArrayBufferOOB(ctx);
1712
+ /* the buffer could have been resized in js_create_from_ctor() (a RangeError, as in
1713
+ QuickJS 2026-06-04 and the specification) */
1714
+ if (offset > abuf.data.length)
1715
+ return JS_ThrowRangeError(ctx, 'invalid byteOffset or byteLength');
1716
+ if (recompute_len)
1717
+ len = abuf.data.length - offset;
1718
+ else if (offset + len > abuf.data.length)
1719
+ return JS_ThrowRangeError(ctx, 'invalid byteOffset or byteLength');
1659
1720
  const ta = new JSTypedArray(buffer, offset, len);
1660
1721
  ta.track_rab = track_rab;
1661
1722
  let view;
@@ -1668,7 +1729,7 @@ function js_dataview_constructor(ctx, new_target, argv) {
1668
1729
  return host_view_adopt(ctx, obj, view, ta);
1669
1730
  }
1670
1731
  function js_dataview_getValue(ctx, this_obj, argv, class_id) {
1671
- const ta = JS_GetOpaque2(ctx, this_obj, 32 /* JSClassID.DATAVIEW */);
1732
+ const ta = JS_GetOpaque2(ctx, this_obj, 33 /* JSClassID.DATAVIEW */);
1672
1733
  if (!ta)
1673
1734
  return JS_EXCEPTION;
1674
1735
  const size = 1 << typed_array_size_log2(class_id);
@@ -1695,13 +1756,14 @@ function js_dataview_getValue(ctx, this_obj, argv, class_id) {
1695
1756
  case 27 /* JSClassID.UINT32_ARRAY */: return dv.getUint32(ptr, littleEndian);
1696
1757
  case 28 /* JSClassID.BIG_INT64_ARRAY */: return dv.getBigInt64(ptr, littleEndian);
1697
1758
  case 29 /* JSClassID.BIG_UINT64_ARRAY */: return dv.getBigUint64(ptr, littleEndian);
1698
- case 30 /* JSClassID.FLOAT32_ARRAY */: return dv.getFloat32(ptr, littleEndian);
1699
- case 31 /* JSClassID.FLOAT64_ARRAY */: return dv.getFloat64(ptr, littleEndian);
1759
+ case 30 /* JSClassID.FLOAT16_ARRAY */: return fromfp16(dv.getUint16(ptr, littleEndian));
1760
+ case 31 /* JSClassID.FLOAT32_ARRAY */: return dv.getFloat32(ptr, littleEndian);
1761
+ case 32 /* JSClassID.FLOAT64_ARRAY */: return dv.getFloat64(ptr, littleEndian);
1700
1762
  default: return JS_ThrowTypeError(ctx, 'invalid DataView type');
1701
1763
  }
1702
1764
  }
1703
1765
  function js_dataview_setValue(ctx, this_obj, argv, class_id) {
1704
- const ta = JS_GetOpaque2(ctx, this_obj, 32 /* JSClassID.DATAVIEW */);
1766
+ const ta = JS_GetOpaque2(ctx, this_obj, 33 /* JSClassID.DATAVIEW */);
1705
1767
  if (!ta)
1706
1768
  return JS_EXCEPTION;
1707
1769
  const size = 1 << typed_array_size_log2(class_id);
@@ -1753,14 +1815,17 @@ function js_dataview_setValue(ctx, this_obj, argv, class_id) {
1753
1815
  case 27 /* JSClassID.UINT32_ARRAY */:
1754
1816
  dv.setUint32(ptr, v, littleEndian);
1755
1817
  break;
1756
- case 30 /* JSClassID.FLOAT32_ARRAY */:
1818
+ case 30 /* JSClassID.FLOAT16_ARRAY */:
1819
+ dv.setUint16(ptr, tofp16(v), littleEndian);
1820
+ break;
1821
+ case 31 /* JSClassID.FLOAT32_ARRAY */:
1757
1822
  dv.setFloat32(ptr, v, littleEndian);
1758
1823
  break;
1759
1824
  case 28 /* JSClassID.BIG_INT64_ARRAY */:
1760
1825
  case 29 /* JSClassID.BIG_UINT64_ARRAY */:
1761
1826
  dv.setBigInt64(ptr, v64, littleEndian);
1762
1827
  break;
1763
- case 31 /* JSClassID.FLOAT64_ARRAY */:
1828
+ case 32 /* JSClassID.FLOAT64_ARRAY */:
1764
1829
  dv.setFloat64(ptr, v, littleEndian);
1765
1830
  break;
1766
1831
  default:
@@ -1780,8 +1845,9 @@ const js_dataview_proto_funcs = [
1780
1845
  JS_CFUNC_MAGIC_DEF('getUint32', 1, js_dataview_getValue, 27 /* JSClassID.UINT32_ARRAY */),
1781
1846
  JS_CFUNC_MAGIC_DEF('getBigInt64', 1, js_dataview_getValue, 28 /* JSClassID.BIG_INT64_ARRAY */),
1782
1847
  JS_CFUNC_MAGIC_DEF('getBigUint64', 1, js_dataview_getValue, 29 /* JSClassID.BIG_UINT64_ARRAY */),
1783
- JS_CFUNC_MAGIC_DEF('getFloat32', 1, js_dataview_getValue, 30 /* JSClassID.FLOAT32_ARRAY */),
1784
- JS_CFUNC_MAGIC_DEF('getFloat64', 1, js_dataview_getValue, 31 /* JSClassID.FLOAT64_ARRAY */),
1848
+ JS_CFUNC_MAGIC_DEF('getFloat16', 1, js_dataview_getValue, 30 /* JSClassID.FLOAT16_ARRAY */),
1849
+ JS_CFUNC_MAGIC_DEF('getFloat32', 1, js_dataview_getValue, 31 /* JSClassID.FLOAT32_ARRAY */),
1850
+ JS_CFUNC_MAGIC_DEF('getFloat64', 1, js_dataview_getValue, 32 /* JSClassID.FLOAT64_ARRAY */),
1785
1851
  JS_CFUNC_MAGIC_DEF('setInt8', 2, js_dataview_setValue, 22 /* JSClassID.INT8_ARRAY */),
1786
1852
  JS_CFUNC_MAGIC_DEF('setUint8', 2, js_dataview_setValue, 23 /* JSClassID.UINT8_ARRAY */),
1787
1853
  JS_CFUNC_MAGIC_DEF('setInt16', 2, js_dataview_setValue, 24 /* JSClassID.INT16_ARRAY */),
@@ -1790,10 +1856,226 @@ const js_dataview_proto_funcs = [
1790
1856
  JS_CFUNC_MAGIC_DEF('setUint32', 2, js_dataview_setValue, 27 /* JSClassID.UINT32_ARRAY */),
1791
1857
  JS_CFUNC_MAGIC_DEF('setBigInt64', 2, js_dataview_setValue, 28 /* JSClassID.BIG_INT64_ARRAY */),
1792
1858
  JS_CFUNC_MAGIC_DEF('setBigUint64', 2, js_dataview_setValue, 29 /* JSClassID.BIG_UINT64_ARRAY */),
1793
- JS_CFUNC_MAGIC_DEF('setFloat32', 2, js_dataview_setValue, 30 /* JSClassID.FLOAT32_ARRAY */),
1794
- JS_CFUNC_MAGIC_DEF('setFloat64', 2, js_dataview_setValue, 31 /* JSClassID.FLOAT64_ARRAY */),
1859
+ JS_CFUNC_MAGIC_DEF('setFloat16', 2, js_dataview_setValue, 30 /* JSClassID.FLOAT16_ARRAY */),
1860
+ JS_CFUNC_MAGIC_DEF('setFloat32', 2, js_dataview_setValue, 31 /* JSClassID.FLOAT32_ARRAY */),
1861
+ JS_CFUNC_MAGIC_DEF('setFloat64', 2, js_dataview_setValue, 32 /* JSClassID.FLOAT64_ARRAY */),
1795
1862
  JS_PROP_STRING_DEF(JS_ATOM_Symbol_toStringTag, 'DataView', JS_PROP_CONFIGURABLE),
1796
1863
  ];
1864
+ /* ---------------------------------------------------------------------
1865
+ Uint8Array base64 / hex (tc39 proposal-arraybuffer-base64)
1866
+ --------------------------------------------------------------------- */
1867
+ /* JS_STRING_LEN_MAX */
1868
+ const JS_STRING_LEN_MAX = (1 << 30) - 1;
1869
+ /* a new Uint8Array holding a copy of 'buf' (JS_NewUint8ArrayCopy) */
1870
+ function JS_NewUint8ArrayCopy(ctx, buf) {
1871
+ const buffer = js_array_buffer_constructor3(ctx, undefined, buf.length, -1, 19 /* JSClassID.ARRAY_BUFFER */, buf);
1872
+ if (JS_IsException(buffer))
1873
+ return JS_EXCEPTION;
1874
+ const obj = js_create_from_ctor(ctx, undefined, 23 /* JSClassID.UINT8_ARRAY */);
1875
+ if (JS_IsException(obj))
1876
+ return JS_EXCEPTION;
1877
+ return typed_array_init(ctx, obj, buffer, 0, buf.length, false);
1878
+ }
1879
+ /* this_val must be a Uint8Array (type check only, no detach check) */
1880
+ function check_uint8array(ctx, this_val) {
1881
+ if (Q.JS_IsObject(this_val) && Q.JS_GetClassID(this_val) === 23 /* JSClassID.UINT8_ARRAY */)
1882
+ return this_val;
1883
+ JS_ThrowTypeError(ctx, 'not a Uint8Array');
1884
+ return null;
1885
+ }
1886
+ /* the bytes of a Uint8Array, checking for detached and out of bounds buffers.
1887
+ Must be called after the options are read (spec ordering). */
1888
+ function get_uint8array_bytes(ctx, p) {
1889
+ if (typed_array_is_oob(ctx, p)) {
1890
+ JS_ThrowTypeErrorArrayBufferOOB(ctx);
1891
+ return null;
1892
+ }
1893
+ return typed_array_get_view(p) ?? new Uint8Array(0);
1894
+ }
1895
+ /* GetOptionsObject: undefined or an object */
1896
+ function check_options_object(ctx, options) {
1897
+ if (JS_IsUndefined(options))
1898
+ return 0;
1899
+ if (!Q.JS_IsObject(options)) {
1900
+ JS_ThrowTypeError(ctx, 'options must be an object');
1901
+ return -1;
1902
+ }
1903
+ return 0;
1904
+ }
1905
+ /* the 'alphabet' option: B64_ALPHABET_xxx or -1 on exception */
1906
+ function parse_alphabet_option(ctx, options) {
1907
+ if (JS_IsUndefined(options))
1908
+ return B64_ALPHABET_BASE64;
1909
+ const val = JS_GetPropertyStr(ctx, options, 'alphabet');
1910
+ if (JS_IsException(val))
1911
+ return -1;
1912
+ if (JS_IsUndefined(val))
1913
+ return B64_ALPHABET_BASE64;
1914
+ if (typeof val !== 'string') {
1915
+ JS_ThrowTypeError(ctx, 'expected string for alphabet');
1916
+ return -1;
1917
+ }
1918
+ if (val === 'base64')
1919
+ return B64_ALPHABET_BASE64;
1920
+ if (val === 'base64url')
1921
+ return B64_ALPHABET_BASE64URL;
1922
+ JS_ThrowTypeError(ctx, 'invalid alphabet');
1923
+ return -1;
1924
+ }
1925
+ /* the 'lastChunkHandling' option: B64_LAST_xxx or -1 on exception */
1926
+ function parse_last_chunk_option(ctx, options) {
1927
+ if (JS_IsUndefined(options))
1928
+ return B64_LAST_LOOSE;
1929
+ const val = JS_GetPropertyStr(ctx, options, 'lastChunkHandling');
1930
+ if (JS_IsException(val))
1931
+ return -1;
1932
+ if (JS_IsUndefined(val))
1933
+ return B64_LAST_LOOSE;
1934
+ if (typeof val !== 'string') {
1935
+ JS_ThrowTypeError(ctx, 'expected string for lastChunkHandling');
1936
+ return -1;
1937
+ }
1938
+ if (val === 'loose')
1939
+ return B64_LAST_LOOSE;
1940
+ if (val === 'strict')
1941
+ return B64_LAST_STRICT;
1942
+ if (val === 'stop-before-partial')
1943
+ return B64_LAST_STOP_BEFORE_PARTIAL;
1944
+ JS_ThrowTypeError(ctx, 'invalid lastChunkHandling option');
1945
+ return -1;
1946
+ }
1947
+ /* Uint8Array.prototype.toBase64([options]) */
1948
+ function js_uint8array_to_base64(ctx, this_val, argv) {
1949
+ const p = check_uint8array(ctx, this_val);
1950
+ if (!p)
1951
+ return JS_EXCEPTION;
1952
+ const options = argv.length > 0 ? argv[0] : undefined;
1953
+ if (check_options_object(ctx, options))
1954
+ return JS_EXCEPTION;
1955
+ const alphabet = parse_alphabet_option(ctx, options);
1956
+ if (alphabet < 0)
1957
+ return JS_EXCEPTION;
1958
+ let omit_padding = false;
1959
+ if (!JS_IsUndefined(options)) {
1960
+ const op_val = JS_GetPropertyStr(ctx, options, 'omitPadding');
1961
+ if (JS_IsException(op_val))
1962
+ return JS_EXCEPTION;
1963
+ omit_padding = JS_ToBoolFree(ctx, op_val);
1964
+ }
1965
+ const data = get_uint8array_bytes(ctx, p);
1966
+ if (!data)
1967
+ return JS_EXCEPTION;
1968
+ if (4 * Math.floor((data.length + 2) / 3) > JS_STRING_LEN_MAX)
1969
+ return JS_ThrowRangeError(ctx, 'output too large');
1970
+ return b64_encode(data, alphabet, omit_padding);
1971
+ }
1972
+ /* Uint8Array.prototype.toHex() */
1973
+ function js_uint8array_to_hex(ctx, this_val, argv) {
1974
+ const p = check_uint8array(ctx, this_val);
1975
+ if (!p)
1976
+ return JS_EXCEPTION;
1977
+ const data = get_uint8array_bytes(ctx, p);
1978
+ if (!data)
1979
+ return JS_EXCEPTION;
1980
+ if (data.length * 2 > JS_STRING_LEN_MAX)
1981
+ return JS_ThrowRangeError(ctx, 'output too large');
1982
+ return u8a_hex_encode(data);
1983
+ }
1984
+ /* Uint8Array.fromBase64(string[, options]) */
1985
+ function js_uint8array_from_base64(ctx, this_val, argv) {
1986
+ const str = argv[0];
1987
+ if (typeof str !== 'string')
1988
+ return JS_ThrowTypeError(ctx, 'expected string');
1989
+ const options = argv.length > 1 ? argv[1] : undefined;
1990
+ if (check_options_object(ctx, options))
1991
+ return JS_EXCEPTION;
1992
+ const alphabet = parse_alphabet_option(ctx, options);
1993
+ if (alphabet < 0)
1994
+ return JS_EXCEPTION;
1995
+ const last_chunk = parse_last_chunk_option(ctx, options);
1996
+ if (last_chunk < 0)
1997
+ return JS_EXCEPTION;
1998
+ const out_cap = Math.floor(str.length / 4) * 3 + 3;
1999
+ const buf = new Uint8Array(out_cap);
2000
+ const r = from_base64(str, buf, out_cap, alphabet, last_chunk);
2001
+ if (r.err)
2002
+ return JS_ThrowSyntaxError(ctx, 'invalid base64 string');
2003
+ return JS_NewUint8ArrayCopy(ctx, buf.subarray(0, r.written));
2004
+ }
2005
+ /* Uint8Array.fromHex(string) */
2006
+ function js_uint8array_from_hex(ctx, this_val, argv) {
2007
+ const str = argv[0];
2008
+ if (typeof str !== 'string')
2009
+ return JS_ThrowTypeError(ctx, 'expected string');
2010
+ const out_cap = Math.floor(str.length / 2) + 1;
2011
+ const buf = new Uint8Array(out_cap);
2012
+ const r = u8a_hex_decode(str, buf, out_cap);
2013
+ if (r.err)
2014
+ return JS_ThrowSyntaxError(ctx, 'invalid hex string');
2015
+ return JS_NewUint8ArrayCopy(ctx, buf.subarray(0, r.written));
2016
+ }
2017
+ /* a { read, written } result object */
2018
+ function js_make_read_written(ctx, read, written) {
2019
+ const obj = JS_NewObject(ctx);
2020
+ if (JS_IsException(obj))
2021
+ return JS_EXCEPTION;
2022
+ if (JS_DefinePropertyValueStr(ctx, obj, 'read', read, JS_PROP_C_W_E) < 0)
2023
+ return JS_EXCEPTION;
2024
+ if (JS_DefinePropertyValueStr(ctx, obj, 'written', written, JS_PROP_C_W_E) < 0)
2025
+ return JS_EXCEPTION;
2026
+ return obj;
2027
+ }
2028
+ /* Uint8Array.prototype.setFromBase64(string[, options]) */
2029
+ function js_uint8array_set_from_base64(ctx, this_val, argv) {
2030
+ const p = check_uint8array(ctx, this_val);
2031
+ if (!p)
2032
+ return JS_EXCEPTION;
2033
+ const str = argv[0];
2034
+ if (typeof str !== 'string')
2035
+ return JS_ThrowTypeError(ctx, 'expected string');
2036
+ const options = argv.length > 1 ? argv[1] : undefined;
2037
+ if (check_options_object(ctx, options))
2038
+ return JS_EXCEPTION;
2039
+ const alphabet = parse_alphabet_option(ctx, options);
2040
+ if (alphabet < 0)
2041
+ return JS_EXCEPTION;
2042
+ const last_chunk = parse_last_chunk_option(ctx, options);
2043
+ if (last_chunk < 0)
2044
+ return JS_EXCEPTION;
2045
+ const data = get_uint8array_bytes(ctx, p);
2046
+ if (!data)
2047
+ return JS_EXCEPTION;
2048
+ const r = from_base64(str, data, data.length, alphabet, last_chunk);
2049
+ if (r.err)
2050
+ return JS_ThrowSyntaxError(ctx, 'invalid base64 string');
2051
+ return js_make_read_written(ctx, r.read, r.written);
2052
+ }
2053
+ /* Uint8Array.prototype.setFromHex(string) */
2054
+ function js_uint8array_set_from_hex(ctx, this_val, argv) {
2055
+ const p = check_uint8array(ctx, this_val);
2056
+ if (!p)
2057
+ return JS_EXCEPTION;
2058
+ const str = argv[0];
2059
+ if (typeof str !== 'string')
2060
+ return JS_ThrowTypeError(ctx, 'expected string');
2061
+ const data = get_uint8array_bytes(ctx, p);
2062
+ if (!data)
2063
+ return JS_EXCEPTION;
2064
+ const r = u8a_hex_decode(str, data, data.length);
2065
+ if (r.err)
2066
+ return JS_ThrowSyntaxError(ctx, 'invalid hex string');
2067
+ return js_make_read_written(ctx, r.read, r.written);
2068
+ }
2069
+ const js_uint8array_proto_funcs = [
2070
+ JS_CFUNC_DEF('toBase64', 0, js_uint8array_to_base64),
2071
+ JS_CFUNC_DEF('toHex', 0, js_uint8array_to_hex),
2072
+ JS_CFUNC_DEF('setFromBase64', 1, js_uint8array_set_from_base64),
2073
+ JS_CFUNC_DEF('setFromHex', 1, js_uint8array_set_from_hex),
2074
+ ];
2075
+ const js_uint8array_funcs = [
2076
+ JS_CFUNC_DEF('fromBase64', 1, js_uint8array_from_base64),
2077
+ JS_CFUNC_DEF('fromHex', 1, js_uint8array_from_hex),
2078
+ ];
1797
2079
  /* ---------------------------------------------------------------------
1798
2080
  Intrinsics
1799
2081
  --------------------------------------------------------------------- */
@@ -1820,6 +2102,8 @@ export function JS_AddIntrinsicTypedArrays(ctx) {
1820
2102
  JS_SetPropertyFunctionList(ctx, typed_array_base_func, js_typed_array_base_funcs);
1821
2103
  JS_SetConstructor(ctx, typed_array_base_func, typed_array_base_proto);
1822
2104
  for (let i = 21 /* JSClassID.UINT8C_ARRAY */; i < 21 /* JSClassID.UINT8C_ARRAY */ + JS_TYPED_ARRAY_COUNT; i++) {
2105
+ if (!typed_array_class_available(i))
2106
+ continue; /* Float16Array on hosts without it */
1823
2107
  const proto = JS_NewObjectProto(ctx, typed_array_base_proto);
1824
2108
  ctx.class_proto[i] = proto;
1825
2109
  JS_DefinePropertyValueStr(ctx, proto, 'BYTES_PER_ELEMENT', 1 << typed_array_size_log2(i), 0);
@@ -1827,10 +2111,14 @@ export function JS_AddIntrinsicTypedArrays(ctx) {
1827
2111
  const func_obj = JS_NewCFunction3(ctx, js_typed_array_constructor, name, 3, 3 /* JSCFunctionEnum.constructor_magic */, i, typed_array_base_func);
1828
2112
  JS_NewGlobalCConstructor2(ctx, func_obj, name, proto);
1829
2113
  JS_DefinePropertyValueStr(ctx, func_obj, 'BYTES_PER_ELEMENT', 1 << typed_array_size_log2(i), 0);
2114
+ if (i === 23 /* JSClassID.UINT8_ARRAY */) {
2115
+ JS_SetPropertyFunctionList(ctx, func_obj, js_uint8array_funcs);
2116
+ JS_SetPropertyFunctionList(ctx, proto, js_uint8array_proto_funcs);
2117
+ }
1830
2118
  }
1831
2119
  /* DataView */
1832
2120
  const dv_proto = JS_NewObject(ctx);
1833
- ctx.class_proto[32 /* JSClassID.DATAVIEW */] = dv_proto;
2121
+ ctx.class_proto[33 /* JSClassID.DATAVIEW */] = dv_proto;
1834
2122
  JS_SetPropertyFunctionList(ctx, dv_proto, js_dataview_proto_funcs);
1835
2123
  JS_NewGlobalCConstructorOnly(ctx, 'DataView', js_dataview_constructor, 1, dv_proto);
1836
2124
  }