You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This introduces an IndexValue typedef, which is a union of Number and
BigInt, and two algorithms, IndexValueToU64 and U64ToIndexValue, which
can be used to convert between IndexValue and WebAssembly's u64 type
(used in the embedding spec).
It also makes several drive-by fixes and improvements.
typedef ([EnforceRange] unsigned long long or bigint) IndexValue;
572
+
564
573
dictionary ModuleExportDescriptor {
565
574
required USVString name;
566
575
required ImportExportKind kind;
@@ -665,15 +674,15 @@ Note: The use of this synchronous API is discouraged, as some implementations so
665
674
666
675
<pre class="idl">
667
676
dictionary MemoryDescriptor {
668
-
required [EnforceRange] unsigned long long initial;
669
-
[EnforceRange] unsigned long long maximum;
677
+
required IndexValue initial;
678
+
IndexValue maximum;
670
679
IndexType index;
671
680
};
672
681
673
682
[LegacyNamespace=WebAssembly, Exposed=*]
674
683
interface Memory {
675
684
constructor(MemoryDescriptor descriptor);
676
-
unsigned long grow([EnforceRange] unsigned long long delta);
685
+
unsigned long grow(IndexValue delta);
677
686
ArrayBuffer toFixedLengthBuffer();
678
687
ArrayBuffer toResizableBuffer();
679
688
readonly attribute ArrayBuffer buffer;
@@ -736,11 +745,11 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
736
745
737
746
<div algorithm>
738
747
The <dfn constructor for="Memory">Memory(|descriptor|)</dfn> constructor, when invoked, performs the following steps:
739
-
1. Let |initial| be |descriptor|["initial"].
740
-
1. If |descriptor|["maximum"][=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty.
748
+
1. If |descriptor|["index"][=map/exists=], let |indextype| be |descriptor|["index"]; otherwise, let |indextype| be "i32".
749
+
1. Let |initial| be [=?=][=IndexValueToU64=](|descriptor|["initial"], |indextype|).
750
+
1. If |descriptor|["maximum"][=map/exists=], let |maximum| be [=?=][=IndexValueToU64=](|descriptor|["maximum"], |indextype|); otherwise, let |maximum| be empty.
741
751
1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception.
742
-
1. If |descriptior|["index"][=map/exists=], let |index| be |descriptor|["index"]; otherwise, let |index| be "i32".
743
-
1. Let |memtype| be { min |initial|, max |maximum|, index |index| }.
752
+
1. Let |memtype| be |indextype| { **min** |initial|, **max** |maximum| }.
744
753
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
745
754
1. Let (|store|, |memaddr|) be [=mem_alloc=](|store|, |memtype|). If allocation fails, throw a {{RangeError}} exception.
746
755
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
@@ -779,7 +788,10 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
779
788
<div algorithm=dom-Memory-grow>
780
789
The <dfn method for="Memory">grow(|delta|)</dfn> method, when invoked, performs the following steps:
781
790
1. Let |memaddr| be **this**.\[[Memory]].
782
-
1. Return the result of [=grow the memory buffer|growing the memory buffer=] associated with |memaddr| by |delta|.
791
+
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
792
+
1. Let |indextype| be the [=index type=] in [=mem_type=](|store|, |memaddr|).
793
+
1. Let |delta64| be [=?=][=IndexValueToU64=](|delta|, |indextype|).
794
+
1. Return the result of [=grow the memory buffer|growing the memory buffer=] associated with |memaddr| by |delta64|.
783
795
</div>
784
796
785
797
Immediately after a WebAssembly [=memory.grow=] instruction executes, perform the following steps:
@@ -857,18 +869,18 @@ enum TableKind {
857
869
858
870
dictionary TableDescriptor {
859
871
required TableKind element;
860
-
required [EnforceRange] unsigned long long initial;
861
-
[EnforceRange] unsigned long long maximum;
872
+
required IndexValue initial;
873
+
IndexValue maximum;
862
874
IndexType index;
863
875
};
864
876
865
877
[LegacyNamespace=WebAssembly, Exposed=*]
866
878
interface Table {
867
879
constructor(TableDescriptor descriptor, optional any value);
868
-
unsigned long long grow([EnforceRange] unsigned long long delta, optional any value);
869
-
any get([EnforceRange] unsigned long long index);
870
-
undefined set([EnforceRange] unsigned long long index, optional any value);
871
-
readonly attribute unsigned long length;
880
+
IndexValue grow(IndexValue delta, optional any value);
881
+
any get(IndexValue index);
882
+
undefined set(IndexValue index, optional any value);
883
+
readonly attribute IndexValue length;
872
884
};
873
885
</pre>
874
886
@@ -896,19 +908,19 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
896
908
897
909
<div algorithm>
898
910
The <dfn constructor for="Table">Table(|descriptor|, |value|)</dfn> constructor, when invoked, performs the following steps:
899
-
1. Let |elementType| be [=ToValueType=](|descriptor|["element"]).
900
-
1. If |elementType| is not a [=reftype=],
901
-
1. Throw a {{TypeError}} exception.
902
-
1. Let |initial| be |descriptor|["initial"].
903
-
1. If |descriptor|["maximum"][=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty.
911
+
1. Let |elementtype| be [=ToValueType=](|descriptor|["element"]).
912
+
1. If |elementtype| is not a [=reftype=],
913
+
1. [=Throw=] a {{TypeError}} exception.
914
+
1. If |descriptor|["index"][=map/exists=], let |indextype| be |descriptor|["index"]; otherwise, let |indextype| be "i32".
915
+
1. Let |initial| be [=?=][=IndexValueToU64=](|descriptor|["initial"], |indextype|).
916
+
1. If |descriptor|["maximum"][=map/exists=], let |maximum| be [=?=][=IndexValueToU64=](|descriptor|["maximum"], |indextype|); otherwise, let |maximum| be empty.
904
917
1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception.
905
918
1. If |value| is missing,
906
-
1. Let |ref| be [=DefaultValue=](|elementType|).
919
+
1. Let |ref| be [=DefaultValue=](|elementtype|).
907
920
1. Assert: |ref| is not [=error=].
908
921
1. Otherwise,
909
-
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementType|).
910
-
1. If |descriptior|["index"][=map/exists=], let |index| be |descriptor|["index"]; otherwise, let |index| be "i32".
911
-
1. Let |type| be the [=table type=][=table type|index=] |index| {[=table type|min=] |initial|, [=table type|max=] |maximum|} [=table type|refType=] |elementType|.
922
+
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementtype|).
923
+
1. Let |type| be the [=table type=] (|indextype|, { **min** |initial|, **max** |maximum| }, |elementtype|).
912
924
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
913
925
1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). <!-- TODO(littledan): Report allocation failure https://github.com/WebAssembly/spec/issues/584 -->
914
926
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
@@ -920,13 +932,14 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
920
932
1. Let |tableaddr| be **this**.\[[Table]].
921
933
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
922
934
1. Let |initialSize| be [=table_size=](|store|, |tableaddr|).
923
-
1. Let (<var ignore>limits</var>, |elementType|) be [=table_type=](|tableaddr|).
935
+
1. Let (|indextype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
936
+
1. Let |delta64| be [=?=][=IndexValueToU64=](|delta|, |indextype|).
924
937
1. If |value| is missing,
925
-
1. Let |ref| be [=DefaultValue=](|elementType|).
938
+
1. Let |ref| be [=DefaultValue=](|elementtype|).
926
939
1. If |ref| is [=error=], throw a {{TypeError}} exception.
927
940
1. Otherwise,
928
-
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementType|).
929
-
1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta|, |ref|).
941
+
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementtype|).
942
+
1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta64|, |ref|).
930
943
1. If |result| is [=error=], throw a {{RangeError}} exception.
931
944
932
945
Note: The above exception can happen due to either insufficient memory or an invalid size parameter.
@@ -939,17 +952,20 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
939
952
The getter of the <dfn attribute for="Table">length</dfn> attribute of {{Table}}, when invoked, performs the following steps:
940
953
1. Let |tableaddr| be **this**.\[[Table]].
941
954
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
942
-
1. Return [=table_size=](|store|, |tableaddr|).
955
+
1. Let |indextype| be the [=index type=] in [=table_type=](|store|, |tableaddr|).
956
+
1. Let |length64| be [=table_size=](|store|, |tableaddr|).
The <dfn method for="Table">get(|index|)</dfn> method, when invoked, performs the following steps:
947
962
1. Let |tableaddr| be **this**.\[[Table]].
948
963
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
949
-
1. Let (<var ignore>limits</var>, |elementType|) be [=table_type=](|store|, |tableaddr|).
950
-
1. If |elementType| is [=exnref=],
964
+
1. Let (|indextype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
965
+
1. If |elementtype| is [=exnref=],
951
966
1. Throw a {{TypeError}} exception.
952
-
1. Let |result| be [=table_read=](|store|, |tableaddr|, |index|).
967
+
1. Let |index64| be [=?=][=IndexValueToU64=](|index|, |indextype|).
968
+
1. Let |result| be [=table_read=](|store|, |tableaddr|, |index64|).
953
969
1. If |result| is [=error=], throw a {{RangeError}} exception.
954
970
1. Return [=ToJSValue=](|result|).
955
971
</div>
@@ -958,16 +974,16 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
958
974
The <dfn method for="Table">set(|index|, |value|)</dfn> method, when invoked, performs the following steps:
959
975
1. Let |tableaddr| be **this**.\[[Table]].
960
976
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
961
-
1. Let (<var ignore>limits</var>, |elementType|) be [=table_type=](|store|, |tableaddr|).
962
-
1. If |elementType| is [=exnref=],
977
+
1. Let (|indextype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
978
+
1. If |elementtype| is [=exnref=],
963
979
1. Throw a {{TypeError}} exception.
980
+
1. Let |index64| be [=?=][=IndexValueToU64=](|index|, |indextype|).
964
981
1. If |value| is missing,
965
-
1. Let |ref| be [=DefaultValue=](|elementType|).
982
+
1. Let |ref| be [=DefaultValue=](|elementtype|).
966
983
1. If |ref| is [=error=], throw a {{TypeError}} exception.
967
984
1. Otherwise,
968
-
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementType|).
969
-
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
970
-
1. Let |store| be [=table_write=](|store|, |tableaddr|, |index|, |ref|).
985
+
1. Let |ref| be [=?=][=ToWebAssemblyValue=](|value|, |elementtype|).
986
+
1. Let |store| be [=table_write=](|store|, |tableaddr|, |index64|, |ref|).
971
987
1. If |store| is [=error=], throw a {{RangeError}} exception.
972
988
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
973
989
</div>
@@ -1236,18 +1252,18 @@ The algorithm <dfn>ToJSValue</dfn>(|w|) coerces a [=WebAssembly value=] to a Jav
1236
1252
1. Assert: |w| is not of the form [=ref.exn=]<var ignore>exnaddr</var>.
1237
1253
1. If |w| is of the form [=i64.const=] |u64|,
1238
1254
1. Let |i64| be [=signed_64=](|u64|).
1239
-
1. Return [=ℤ=](|i64| interpreted as a mathematical value).
1240
-
1. If |w| is of the form [=i32.const=] |i32|,
1241
-
1. Let |i32| be [=signed_32=](|i32|).
1242
-
2. Return [=𝔽=](|i32| interpreted as a mathematical value).
1255
+
1. Return [=ℤ=](|i64| interpreted as a [=mathematical value=]).
1256
+
1. If |w| is of the form [=i32.const=] |u32|,
1257
+
1. Let |i32| be [=signed_32=](|u32|).
1258
+
2. Return [=𝔽=](|i32| interpreted as a [=mathematical value=]).
1243
1259
1. If |w| is of the form [=f32.const=] |f32|,
1244
1260
1. If |f32| is [=+∞=] or [=−∞=], return **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, respectively.
1245
1261
1. If |f32| is [=nan=], return **NaN**.
1246
-
1. Return [=𝔽=](|f32| interpreted as a mathematical value).
1262
+
1. Return [=𝔽=](|f32| interpreted as a [=mathematical value=]).
1247
1263
1. If |w| is of the form [=f64.const=] |f64|,
1248
1264
1. If |f64| is [=+∞=] or [=−∞=], return **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, respectively.
1249
1265
1. If |f64| is [=nan=], return **NaN**.
1250
-
1. Return [=𝔽=](|f64| interpreted as a mathematical value).
1266
+
1. Return [=𝔽=](|f64| interpreted as a [=mathematical value=]).
1251
1267
1. If |w| is of the form [=ref.null=]<var ignore>t</var>, return null.
1252
1268
1. If |w| is of the form [=ref.i31=] |u31|,
1253
1269
1. Let |i31| be [=signed_31=](|u31|).
@@ -1288,15 +1304,15 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
1288
1304
1. If |type| is [=f32=],
1289
1305
1. Let |number| be [=?=][$ToNumber$](|v|).
1290
1306
1. If |number| is **NaN**,
1291
-
1. Let |n| be an implementation-defined integer such that [=canon=]<sub>32</sub>≤ |n| < 2<sup>[=signif=](32)</sup>.
1307
+
1. Let |n| be an implementation-defined integer such that [=canon=]<sub>32</sub>≤ |n| < 2<sup>[=signif=](32)</sup>.
1292
1308
1. Let |f32| be [=nan=](n).
1293
1309
1. Otherwise,
1294
1310
1. Let |f32| be |number| rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode. [[IEEE-754]]
1295
1311
1. Return [=f32.const=] |f32|.
1296
1312
1. If |type| is [=f64=],
1297
1313
1. Let |number| be [=?=][$ToNumber$](|v|).
1298
1314
1. If |number| is **NaN**,
1299
-
1. Let |n| be an implementation-defined integer such that [=canon=]<sub>64</sub>≤ |n| < 2<sup>[=signif=](64)</sup>.
1315
+
1. Let |n| be an implementation-defined integer such that [=canon=]<sub>64</sub>≤ |n| < 2<sup>[=signif=](64)</sup>.
1300
1316
1. Let |f64| be [=nan=](n).
1301
1317
1. Otherwise,
1302
1318
1. Let |f64| be |number|.
@@ -1337,6 +1353,31 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
1337
1353
1338
1354
</div>
1339
1355
1356
+
<div algorithm>
1357
+
The algorithm <dfn>IndexValueToU64</dfn>(|v|, |indextype|) asserts that a JavaScript value is the appropriate variant of {{IndexValue}} for an {{IndexType}}, and ensures that its value is in [=u64=] range for WebAssembly embedding operations, by performing the following steps:
1358
+
1359
+
1. If |indextype| is "i32",
1360
+
1. If |v| [=is a Number=],
1361
+
1. Assert: Due to WebIDL types and [=[EnforceRange]=], 0 ≤ [=ℝ=](|v|) < 2<sup>64</sup>.
1362
+
1. Return [=ℝ=](|v|) as a WebAssembly [=u64=].
1363
+
1. Otherwise, [=throw=] a {{TypeError}}.
1364
+
1. Else if |indextype| is "i64",
1365
+
1. If |v| [=is a BigInt=],
1366
+
1. If |v| is not equal to [=!=][$ToBigUint64$](|v|), [=throw=] a {{RangeError}}.
1367
+
1. Return [=ℝ=](|v|) as a WebAssembly [=u64=].
1368
+
1. Otherwise, [=throw=] a {{TypeError}}.
1369
+
1. Assert: This step is not reached.
1370
+
1371
+
</div>
1372
+
1373
+
<div algorithm>
1374
+
The algorithm <dfn>U64ToIndexValue</dfn>(|v|, |indextype|) converts a [=u64=] value from a WebAssembly embedding operation to the correct variant of {{IndexValue}} for an {{IndexType}}, by performing the following steps:
1375
+
1376
+
1. If |indextype| is "i32", return [=𝔽=](|v| interpreted as a [=mathematical value=]).
1377
+
1. Else if |indextype| is "i64", return [=ℤ=](|v| interpreted as a [=mathematical value=]).
1378
+
1. Assert: This step is not reached.
1379
+
1380
+
</div>
1340
1381
1341
1382
<h3 id="tags">Tags</h3>
1342
1383
@@ -1369,7 +1410,6 @@ To <dfn>initialize a Tag object</dfn> |tag| from a [=tag address=] |tagAddress|,
1369
1410
</div>
1370
1411
1371
1412
<div algorithm>
1372
-
1373
1413
To <dfn>create a Tag object</dfn> from a [=tag address=] |tagAddress|, perform the following steps:
1374
1414
1375
1415
1. Let |map| be the [=surrounding agent=]'s associated [=Tag object cache=].
0 commit comments