Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit d258902

Browse files
authored
[spec/interpreter] Fix missing multi table bulk cases (#80)
1 parent fc990e3 commit d258902

File tree

7 files changed

+113
-54
lines changed

7 files changed

+113
-54
lines changed

document/core/appendix/index-rules.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ Construct Judgement
2626
:ref:`Table <valid-table>` :math:`C \vdashtable \table : \tabletype`
2727
:ref:`Memory <valid-mem>` :math:`C \vdashmem \mem : \memtype`
2828
:ref:`Global <valid-global>` :math:`C \vdashglobal \global : \globaltype`
29-
:ref:`Element segment <valid-elem>` :math:`C \vdashelem \elem \ok`
30-
:ref:`Element mode <valid-elemmode>` :math:`C \vdashelemmode \elemmode \ok`
29+
:ref:`Element segment <valid-elem>` :math:`C \vdashelem \elem : \reftype`
30+
:ref:`Element mode <valid-elemmode>` :math:`C \vdashelemmode \elemmode : \reftype`
3131
:ref:`Data segment <valid-data>` :math:`C \vdashdata \data \ok`
3232
:ref:`Data mode <valid-datamode>` :math:`C \vdashdatamode \datamode \ok`
3333
:ref:`Start function <valid-start>` :math:`C \vdashstart \start \ok`

document/core/binary/instructions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ Table Instructions
157157
\hex{FC}~\hex{0F}~~x{:}\Btableidx &\Rightarrow& \TABLEGROW~x \\ &&|&
158158
\hex{FC}~\hex{10}~~x{:}\Btableidx &\Rightarrow& \TABLESIZE~x \\ &&|&
159159
\hex{FC}~\hex{11}~~x{:}\Btableidx &\Rightarrow& \TABLEFILL~x \\
160-
\hex{FC}~\hex{0C}~~\hex{00}~x{:}\Belemidx &\Rightarrow& \TABLEINIT~x \\ &&|&
160+
\hex{FC}~\hex{0C}~~x{:}\Btableidx~~y{:}\Belemidx &\Rightarrow& \TABLEINIT~x~y \\ &&|&
161161
\hex{FC}~\hex{0D}~~x{:}\Belemidx &\Rightarrow& \ELEMDROP~x \\ &&|&
162-
\hex{FC}~\hex{0E}~~\hex{00}~~\hex{00} &\Rightarrow& \TABLECOPY \\
162+
\hex{FC}~\hex{0E}~~x{:}\Btableidx~~y{:}\Btableidx &\Rightarrow& \TABLECOPY~x~y \\
163163
\end{array}
164164
165165

document/core/valid/conventions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ which collects relevant information about the surrounding :ref:`module <syntax-m
3838
* *Tables*: the list of tables declared in the current module, represented by their table type.
3939
* *Memories*: the list of memories declared in the current module, represented by their memory type.
4040
* *Globals*: the list of globals declared in the current module, represented by their global type.
41-
* *Element Segments*: the list of element segments declared in the current module, each represented by an |ok| entry.
41+
* *Element Segments*: the list of element segments declared in the current module, represented by their element type.
4242
* *Data Segments*: the list of data segments declared in the current module, each represented by an |ok| entry.
4343
* *Locals*: the list of locals declared in the current function (including parameters), represented by their value type.
4444
* *Labels*: the stack of labels accessible from the current position, represented by their result type.
@@ -61,7 +61,7 @@ More concretely, contexts are defined as :ref:`records <notation-record>` :math:
6161
& \CTABLES & \tabletype^\ast, \\
6262
& \CMEMS & \memtype^\ast, \\
6363
& \CGLOBALS & \globaltype^\ast, \\
64-
& \CELEMS & {\ok}^\ast, \\
64+
& \CELEMS & \reftype^\ast, \\
6565
& \CDATAS & {\ok}^\ast, \\
6666
& \CLOCALS & \valtype^\ast, \\
6767
& \CLABELS & \resulttype^\ast, \\

document/core/valid/instructions.rst

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ Table Instructions
431431

432432
.. math::
433433
\frac{
434-
C.\CTABLES[x] = t
434+
C.\CTABLES[x] = \tabletype
435435
}{
436436
C \vdashinstr \TABLESIZE~x : [] \to [\I32]
437437
}
@@ -450,7 +450,7 @@ Table Instructions
450450

451451
.. math::
452452
\frac{
453-
C.\CTABLES[x] = t
453+
C.\CTABLES[x] = \limits~t
454454
}{
455455
C \vdashinstr \TABLEGROW~x : [t~\I32] \to [\I32]
456456
}
@@ -469,47 +469,67 @@ Table Instructions
469469

470470
.. math::
471471
\frac{
472-
C.\CTABLES[x] = t
472+
C.\CTABLES[x] = \limits~t
473473
}{
474474
C \vdashinstr \TABLEFILL~x : [\I32~t~\I32] \to []
475475
}
476476
477477
478478
.. _valid-table.copy:
479479

480-
:math:`\TABLECOPY`
481-
.....................
480+
:math:`\TABLECOPY~x~y`
481+
......................
482+
483+
* The table :math:`C.\CTABLES[x]` must be defined in the context.
484+
485+
* Let :math:`\limits_1~t_1` be the :ref:`table type <syntax-tabletype>` :math:`C.\CTABLES[x]`.
486+
487+
* The table :math:`C.\CTABLES[y]` must be defined in the context.
482488

483-
* The table :math:`C.\CTABLES[0]` must be defined in the context.
489+
* Let :math:`\limits_2~t_2` be the :ref:`table type <syntax-tabletype>` :math:`C.\CTABLES[y]`.
490+
491+
* The :ref:`reference type <syntax-reftype>` :math:`t_2` must :ref:`match <match-reftype>` :math:`t_1`.
484492

485493
* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`.
486494

487495
.. math::
488496
\frac{
489-
C.\CTABLES[0] = \tabletype
497+
C.\CTABLES[x] = \limits_1~t_1
498+
\qquad
499+
C.\CTABLES[x] = \limits_2~t_2
500+
\qquad
501+
\vdashreftypematch t_2 \matchesvaltype t_1
490502
}{
491-
C \vdashinstr \TABLECOPY : [\I32~\I32~\I32] \to []
503+
C \vdashinstr \TABLECOPY~x~y : [\I32~\I32~\I32] \to []
492504
}
493505
494506
495507
.. _valid-table.init:
496508

497-
:math:`\TABLEINIT~x`
498-
.....................
509+
:math:`\TABLEINIT~x~y`
510+
......................
499511

500-
* The table :math:`C.\CTABLES[0]` must be defined in the context.
512+
* The table :math:`C.\CTABLES[x]` must be defined in the context.
501513

502-
* The element segment :math:`C.\CELEMS[x]` must be defined in the context.
514+
* Let :math:`\limits~t_1` be the :ref:`table type <syntax-tabletype>` :math:`C.\CTABLES[x]`.
515+
516+
* The element segment :math:`C.\CELEMS[y]` must be defined in the context.
517+
518+
* Let :math:`t_2` be the :ref:`reference type <syntax-reftype>` :math:`C.\CELEMS[y]`.
519+
520+
* The :ref:`reference type <syntax-reftype>` :math:`t_2` must :ref:`match <match-reftype>` :math:`t_1`.
503521

504522
* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`.
505523

506524
.. math::
507525
\frac{
508-
C.\CTABLES[0] = \tabletype
526+
C.\CTABLES[x] = \limits_1~t_1
527+
\qquad
528+
C.\CELEMS[y] = t_2
509529
\qquad
510-
C.\CELEMS[x] = {\ok}
530+
\vdashreftypematch t_2 \matchesvaltype t_1
511531
}{
512-
C \vdashinstr \TABLEINIT~x : [\I32~\I32~\I32] \to []
532+
C \vdashinstr \TABLEINIT~x~y : [\I32~\I32~\I32] \to []
513533
}
514534
515535
@@ -524,7 +544,7 @@ Table Instructions
524544

525545
.. math::
526546
\frac{
527-
C.\CELEMS[x] = {\ok}
547+
C.\CELEMS[x] = t
528548
}{
529549
C \vdashinstr \ELEMDROP~x : [] \to []
530550
}

document/core/valid/modules.rst

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,22 @@ Globals :math:`\global` are classified by :ref:`global types <syntax-globaltype>
145145
Element Segments
146146
~~~~~~~~~~~~~~~~
147147

148-
Element segments :math:`\elem` are not classified by any type but merely checked for well-formedness.
148+
Element segments :math:`\elem` are classified by the :ref:`reference type <syntax-reftype>` of their elements.
149149

150-
:math:`\{ \ETYPE~et, \EINIT~e^\ast, \EMODE~\elemmode \}`
151-
........................................................
150+
:math:`\{ \ETYPE~t, \EINIT~e^\ast, \EMODE~\elemmode \}`
151+
.......................................................
152152

153153
* For each :math:`e_i` in :math:`e^\ast`,
154154

155155
* The expression :math:`e_i` must be :ref:`valid <valid-expr>`.
156156

157157
* The expression :math:`e_i` must be :ref:`constant <valid-const>`.
158158

159-
* The element mode :math:`\elemmode` must be valid for :ref:`reference type <syntax-reftype>` :math:`\X{et}`.
159+
* The element mode :math:`\elemmode` must be valid with :ref:`reference type <syntax-reftype>` :math:`t'`.
160160

161-
* Then the element segment is valid.
161+
* The :ref:`reference type <syntax-reftype>` :math:`t` must :ref:`match <match-reftype>` the reference type :math:`t'`.
162+
163+
* Then the element segment is valid with :ref:`reference type <syntax-reftype>` :math:`t`.
162164

163165

164166
.. math::
@@ -167,9 +169,11 @@ Element segments :math:`\elem` are not classified by any type but merely checked
167169
\qquad
168170
(C \vdashexprconst e \const)^\ast
169171
\qquad
170-
C; \X{et} \vdashelemmode \elemmode \ok
172+
C \vdashelemmode \elemmode : t'
173+
\qquad
174+
\vdashreftypematch t \matchesvaltype t'
171175
}{
172-
C \vdashelem \{ \ETYPE~et, \EINIT~e^\ast, \EMODE~\elemmode \} \ok
176+
C \vdashelem \{ \ETYPE~t, \EINIT~e^\ast, \EMODE~\elemmode \} : t
173177
}
174178
175179
@@ -178,12 +182,12 @@ Element segments :math:`\elem` are not classified by any type but merely checked
178182
:math:`\EPASSIVE`
179183
.................
180184

181-
* The element mode is valid for any :ref:`reference type <syntax-reftype>` :math:`\X{et}`.
185+
* The element mode is valid with any :ref:`reference type <syntax-reftype>`.
182186

183187
.. math::
184188
\frac{
185189
}{
186-
C; \X{et} \vdashelemmode \EPASSIVE \ok
190+
C \vdashelemmode \EPASSIVE : \reftype
187191
}
188192
189193
@@ -194,38 +198,34 @@ Element segments :math:`\elem` are not classified by any type but merely checked
194198

195199
* Let :math:`\limits~t` be the :ref:`table type <syntax-tabletype>` :math:`C.\CTABLES[x]`.
196200

197-
* The :ref:`reference type <syntax-reftype>` :math:`\X{et}` must :ref:`match <match-reftype>` the reference type :math:`t`.
198-
199201
* The expression :math:`\expr` must be :ref:`valid <valid-expr>` with :ref:`result type <syntax-resulttype>` :math:`[\I32]`.
200202

201203
* The expression :math:`\expr` must be :ref:`constant <valid-constant>`.
202204

203-
* Then the element mode is valid for :ref:`reference type <syntax-reftype>` :math:`\X{et}`.
205+
* Then the element mode is valid with :ref:`reference type <syntax-reftype>` :math:`t`.
204206

205207
.. math::
206208
\frac{
207209
\begin{array}{@{}c@{}}
208210
C.\CTABLES[x] = \limits~t
209-
\qquad
210-
\vdashreftypematch \X{et} \matchesvaltype t
211211
\\
212212
C \vdashexpr \expr : [\I32]
213213
\qquad
214214
C \vdashexprconst \expr \const
215215
\end{array}
216216
}{
217-
C; \X{et} \vdashelemmode \EACTIVE~\{ \ETABLE~x, \EOFFSET~\expr \} \ok
217+
C \vdashelemmode \EACTIVE~\{ \ETABLE~x, \EOFFSET~\expr \} : t
218218
}
219219
220220
:math:`\EDECLARATIVE`
221221
.....................
222222

223-
* The element mode is valid for any :ref:`reference type <syntax-reftype>` :math:`\X{et}`.
223+
* The element mode is valid with any :ref:`reference type <syntax-reftype>`.
224224

225225
.. math::
226226
\frac{
227227
}{
228-
C; \X{et} \vdashelemmode \EDECLARATIVE \ok
228+
C \vdashelemmode \EDECLARATIVE : \reftype
229229
}
230230
231231
@@ -290,7 +290,7 @@ Data segments :math:`\data` are not classified by any type but merely checked fo
290290
\qquad
291291
C \vdashexprconst \expr \const
292292
}{
293-
C \vdashelemmode \DACTIVE~\{ \DMEM~x, \DOFFSET~\expr \} \ok
293+
C \vdashdatamode \DACTIVE~\{ \DMEM~x, \DOFFSET~\expr \} \ok
294294
}
295295
296296
@@ -531,7 +531,7 @@ Instead, the context :math:`C` for validation of the module's content is constru
531531
* :math:`C.\CGLOBALS` is :math:`\etglobals(\X{it}^\ast)` concatenated with :math:`\X{gt}^\ast`,
532532
with the import's :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast` and the internal :ref:`global types <syntax-globaltype>` :math:`\X{gt}^\ast` as determined below,
533533

534-
* :math:`C.\CELEMS` is :math:`{\ok}^{N_e}`, where :math:`N_e` is the length of the vector :math:`\module.\MELEMS`,
534+
* :math:`C.\CELEMS` is :math:`{\X{rt}}^\ast` as determined below,
535535

536536
* :math:`C.\CDATAS` is :math:`{\ok}^{N_d}`, where :math:`N_d` is the length of the vector :math:`\module.\MDATAS`,
537537

@@ -573,7 +573,7 @@ Instead, the context :math:`C` for validation of the module's content is constru
573573
the definition :math:`\global_i` must be :ref:`valid <valid-global>` with a :ref:`global type <syntax-globaltype>` :math:`\X{gt}_i`.
574574

575575
* For each :math:`\elem_i` in :math:`\module.\MELEMS`,
576-
the segment :math:`\elem_i` must be :ref:`valid <valid-elem>`.
576+
the segment :math:`\elem_i` must be :ref:`valid <valid-elem>` with :ref:`reference type <syntax-reftype>` :math:`\X{rt}_i`.
577577

578578
* For each :math:`\data_i` in :math:`\module.\MDATAS`,
579579
the segment :math:`\data_i` must be :ref:`valid <valid-data>`.
@@ -599,6 +599,8 @@ Instead, the context :math:`C` for validation of the module's content is constru
599599

600600
* Let :math:`\X{gt}^\ast` be the concatenation of the internal :ref:`global types <syntax-globaltype>` :math:`\X{gt}_i`, in index order.
601601

602+
* Let :math:`\X{rt}^\ast` be the concatenation of the :ref:`referense types <syntax-reftype>` :math:`\X{rt}_i`, in index order.
603+
602604
* Let :math:`\X{it}^\ast` be the concatenation of :ref:`external types <syntax-externtype>` :math:`\X{it}_i` of the imports, in index order.
603605

604606
* Let :math:`\X{et}^\ast` be the concatenation of :ref:`external types <syntax-externtype>` :math:`\X{et}_i` of the exports, in index order.
@@ -618,7 +620,7 @@ Instead, the context :math:`C` for validation of the module's content is constru
618620
\quad
619621
(C' \vdashglobal \global : \X{gt})^\ast
620622
\\
621-
(C \vdashelem \elem \ok)^{N_e}
623+
(C \vdashelem \elem : \X{rt})^\ast
622624
\quad
623625
(C \vdashdata \data \ok)^{N_d}
624626
\quad
@@ -636,7 +638,7 @@ Instead, the context :math:`C` for validation of the module's content is constru
636638
\qquad
637639
\X{igt}^\ast = \etglobals(\X{it}^\ast)
638640
\\
639-
C = \{ \CTYPES~\functype^\ast, \CFUNCS~\X{ift}^\ast~\X{ft}^\ast, \CTABLES~\X{itt}^\ast~\X{tt}^\ast, \CMEMS~\X{imt}^\ast~\X{mt}^\ast, \CGLOBALS~\X{igt}^\ast~\X{gt}^\ast, \CELEMS~{\ok}^{N_e}, \CDATAS~{\ok}^{N_d}, \CREFS~\freefuncidx(\elem^{N_e}) \}
641+
C = \{ \CTYPES~\functype^\ast, \CFUNCS~\X{ift}^\ast~\X{ft}^\ast, \CTABLES~\X{itt}^\ast~\X{tt}^\ast, \CMEMS~\X{imt}^\ast~\X{mt}^\ast, \CGLOBALS~\X{igt}^\ast~\X{gt}^\ast, \CELEMS~\X{rt}^\ast, \CDATAS~{\ok}^{N_d}, \CREFS~\freefuncidx(\elem^\ast) \}
640642
\\
641643
C' = \{ \CGLOBALS~\X{igt}^\ast, \CFUNCS~(C.\CFUNCS), \CREFS~(C.\CREFS) \}
642644
\qquad
@@ -652,7 +654,7 @@ Instead, the context :math:`C` for validation of the module's content is constru
652654
\MTABLES~\table^\ast,
653655
\MMEMS~\mem^\ast,
654656
\MGLOBALS~\global^\ast, \\
655-
\MELEMS~\elem^{N_e},
657+
\MELEMS~\elem^\ast,
656658
\MDATAS~\data^{N_d},
657659
\MSTART~\start^?,
658660
\MIMPORTS~\import^\ast,

interpreter/valid/valid.ml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ type context =
2121
tables : table_type list;
2222
memories : memory_type list;
2323
globals : global_type list;
24+
elems : ref_type list;
2425
datas : unit list;
25-
elems : unit list;
2626
locals : value_type list;
2727
results : value_type list;
2828
labels : stack_type list;
@@ -31,7 +31,7 @@ type context =
3131

3232
let empty_context =
3333
{ types = []; funcs = []; tables = []; memories = [];
34-
globals = []; datas = []; elems = [];
34+
globals = []; elems = []; datas = [];
3535
locals = []; results = []; labels = [];
3636
refs = Free.empty
3737
}
@@ -45,8 +45,8 @@ let func (c : context) x = lookup "function" c.funcs x
4545
let table (c : context) x = lookup "table" c.tables x
4646
let memory (c : context) x = lookup "memory" c.memories x
4747
let global (c : context) x = lookup "global" c.globals x
48-
let data (c : context) x = lookup "data segment" c.datas x
4948
let elem (c : context) x = lookup "elem segment" c.elems x
49+
let data (c : context) x = lookup "data segment" c.datas x
5050
let local (c : context) x = lookup "local" c.locals x
5151
let label (c : context) x = lookup "label" c.labels x
5252

@@ -288,13 +288,19 @@ let rec check_instr (c : context) (e : instr) (s : infer_stack_type) : op_type =
288288
[NumType I32Type; RefType t; NumType I32Type] --> []
289289

290290
| TableCopy (x, y) ->
291-
ignore (table c x);
292-
ignore (table c y);
291+
let TableType (_lim1, t1) = table c x in
292+
let TableType (_lim2, t2) = table c y in
293+
require (match_ref_type t2 t1) x.at
294+
("type mismatch: source element type " ^ string_of_ref_type t1 ^
295+
" does not match destination element type " ^ string_of_ref_type t2);
293296
[NumType I32Type; NumType I32Type; NumType I32Type] --> []
294297

295298
| TableInit (x, y) ->
296-
ignore (table c x);
297-
ignore (elem c y);
299+
let TableType (_lim1, t1) = table c x in
300+
let t2 = elem c y in
301+
require (match_ref_type t2 t1) x.at
302+
("type mismatch: source element type " ^ string_of_ref_type t1 ^
303+
" does not match destination element type " ^ string_of_ref_type t2);
298304
[NumType I32Type; NumType I32Type; NumType I32Type] --> []
299305

300306
| ElemDrop x ->
@@ -568,8 +574,8 @@ let check_module (m : module_) =
568574
funcs = c0.funcs @ List.map (fun f -> type_ c0 f.it.ftype) funcs;
569575
tables = c0.tables @ List.map (fun tab -> tab.it.ttype) tables;
570576
memories = c0.memories @ List.map (fun mem -> mem.it.mtype) memories;
571-
elems = List.map (fun _ -> ()) elems;
572-
datas = List.map (fun _ -> ()) datas;
577+
elems = List.map (fun elem -> elem.it.etype) elems;
578+
datas = List.map (fun _data -> ()) datas;
573579
}
574580
in
575581
let c =

0 commit comments

Comments
 (0)