Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Commit c3d5cbc

Browse files
authored
[spec/interpreter/test] Add table bulk instructions missing from bulk op proposal (#35)
Adds table.size, table.grow, table.fill to overview, spec, interpreter, and tests, as decided at recent CG meeting. Also adds a few more tests for table.get and table.set. Also, change interpreter's segment encoding to match bulk ops proposal, addressing #18. (Not updated in spec yet, since corresponding spec text is still missing from bulk ops proposal.)
1 parent ef6678a commit c3d5cbc

29 files changed

+975
-70
lines changed

document/core/appendix/embedding.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,16 @@ Tables
294294

295295
.. _embed-alloc-table:
296296

297-
:math:`\F{alloc\_table}(\store, \tabletype) : (\store, \tableaddr)`
298-
...................................................................
297+
:math:`\F{alloc\_table}(\store, \tabletype) : (\store, \tableaddr, \val)`
298+
.........................................................................
299299

300300
1. Let :math:`\tableaddr` be the result of :ref:`allocating a table <alloc-table>` in :math:`\store` with :ref:`table type <syntax-tabletype>` :math:`\tabletype`.
301301

302302
2. Return the new store paired with :math:`\tableaddr`.
303303

304304
.. math::
305305
\begin{array}{lclll}
306-
\F{alloc\_table}(S, \X{tt}) &=& (S', \X{a}) && (\iff \alloctable(S, \X{tt}) = S', \X{a}) \\
306+
\F{alloc\_table}(S, \X{tt}, v) &=& (S', \X{a}) && (\iff \alloctable(S, \X{tt}, v) = S', \X{a}) \\
307307
\end{array}
308308
309309
@@ -390,8 +390,8 @@ Tables
390390
391391
.. _embed-grow-table:
392392

393-
:math:`\F{grow\_table}(\store, \tableaddr, n) : \store ~|~ \error`
394-
..................................................................
393+
:math:`\F{grow\_table}(\store, \tableaddr, n, \val) : \store ~|~ \error`
394+
........................................................................
395395

396396
1. Assert: :math:`\store.\STABLES[\tableaddr]` exists.
397397

@@ -406,9 +406,9 @@ Tables
406406
.. math::
407407
~ \\
408408
\begin{array}{lclll}
409-
\F{grow\_table}(S, a, n) &=& S' &&
410-
(\iff S' = S \with \STABLES[a] = \growtable(S.\STABLES[a], n)) \\
411-
\F{grow\_table}(S, a, n) &=& \ERROR && (\otherwise) \\
409+
\F{grow\_table}(S, a, n, v) &=& S' &&
410+
(\iff S' = S \with \STABLES[a] = \growtable(S.\STABLES[a], n, v)) \\
411+
\F{grow\_table}(S, a, n, v) &=& \ERROR && (\otherwise) \\
412412
\end{array}
413413
414414

document/core/binary/instructions.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,24 @@ Variable Instructions
138138
Table Instructions
139139
~~~~~~~~~~~~~~~~~~
140140

141-
:ref:`Table instructions <syntax-instr-table>` are represented by single byte codes.
141+
:ref:`Table instructions <syntax-instr-table>` are represented by either single byte or two byte codes.
142142

143143
.. _binary-table.get:
144144
.. _binary-table.set:
145+
.. _binary-table.size:
146+
.. _binary-table.grow:
147+
.. _binary-table.fill:
145148

146149
.. math::
147150
\begin{array}{llclll}
148151
\production{instruction} & \Binstr &::=& \dots \\ &&|&
149152
\hex{25}~~x{:}\Btableidx &\Rightarrow& \TABLEGET~x \\ &&|&
150-
\hex{26}~~x{:}\Btableidx &\Rightarrow& \TABLESET~x \\
153+
\hex{26}~~x{:}\Btableidx &\Rightarrow& \TABLESET~x \\ &&|&
154+
\hex{FC}~\hex{0F}~~x{:}\Btableidx &\Rightarrow& \TABLEGROW~x \\ &&|&
155+
\hex{FC}~\hex{10}~~x{:}\Btableidx &\Rightarrow& \TABLESIZE~x \\ &&|&
156+
\hex{FC}~\hex{11}~~x{:}\Btableidx &\Rightarrow& \TABLEFILL~x \\
151157
\end{array}
152158
153-
.. note::
154-
These opcode assignments are preliminary.
155-
156159
157160
.. index:: memory instruction, memory index
158161
pair: binary format; instruction

document/core/exec/instructions.rst

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,162 @@ Table Instructions
522522
\end{array}
523523
524524
525+
.. _exec-table.size:
526+
527+
:math:`\TABLESIZE~x`
528+
....................
529+
530+
1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.
531+
532+
2. Assert: due to :ref:`validation <valid-table.size>`, :math:`F.\AMODULE.\MITABLES[x]` exists.
533+
534+
3. Let :math:`a` be the :ref:`table address <syntax-tableaddr>` :math:`F.\AMODULE.\MITABLES[x]`.
535+
536+
4. Assert: due to :ref:`validation <valid-table.size>`, :math:`S.\STABLES[a]` exists.
537+
538+
5. Let :math:`\X{tab}` be the :ref:`table instance <syntax-tableinst>` :math:`S.\STABLES[a]`.
539+
540+
6. Let :math:`\X{sz}` be the length of :math:`\X{tab}.\TIELEM`.
541+
542+
7. Push the value :math:`\I32.\CONST~\X{sz}` to the stack.
543+
544+
.. math::
545+
\begin{array}{l}
546+
\begin{array}{lcl@{\qquad}l}
547+
S; F; \TABLESIZE~x &\stepto& S; F; (\I32.\CONST~\X{sz})
548+
\end{array}
549+
\\ \qquad
550+
(\iff |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM| = \X{sz}) \\
551+
\end{array}
552+
553+
554+
.. _exec-table.grow:
555+
556+
:math:`\TABLEGROW~x`
557+
....................
558+
559+
1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.
560+
561+
2. Assert: due to :ref:`validation <valid-table.grow>`, :math:`F.\AMODULE.\MITABLES[x]` exists.
562+
563+
3. Let :math:`a` be the :ref:`table address <syntax-tableaddr>` :math:`F.\AMODULE.\MITABLES[x]`.
564+
565+
4. Assert: due to :ref:`validation <valid-table.grow>`, :math:`S.\STABLES[a]` exists.
566+
567+
5. Let :math:`\X{tab}` be the :ref:`table instance <syntax-tableinst>` :math:`S.\STABLES[a]`.
568+
569+
6. Let :math:`\X{sz}` be the length of :math:`S.\STABLES[a]`.
570+
571+
7. Assert: due to :ref:`validation <valid-table.grow>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.
572+
573+
8. Pop the value :math:`\I32.\CONST~n` from the stack.
574+
575+
9. Assert: due to :ref:`validation <valid-table.fill>`, a :ref:`reference value <syntax-ref>` is on the top of the stack.
576+
577+
10. Pop the value :math:`\val` from the stack.
578+
579+
11. Either, try :ref:`growing <grow-table>` :math:`\X{table}` by :math:`n` entries with initialization value :math:`\val`:
580+
581+
a. If it succeeds, push the value :math:`\I32.\CONST~\X{sz}` to the stack.
582+
583+
b. Else, push the value :math:`\I32.\CONST~(-1)` to the stack.
584+
585+
12. Or, push the value :math:`\I32.\CONST~(-1)` to the stack.
586+
587+
.. math::
588+
~\\[-1ex]
589+
\begin{array}{l}
590+
\begin{array}{lcl@{\qquad}l}
591+
S; F; \val~(\I32.\CONST~n)~\TABLEGROW~x &\stepto& S'; F; (\I32.\CONST~\X{sz})
592+
\end{array}
593+
\\ \qquad
594+
\begin{array}[t]{@{}r@{~}l@{}}
595+
(\iff & F.\AMODULE.\MITABLES[x] = a \\
596+
\wedge & \X{sz} = |S.\STABLES[a].\TIELEM| \\
597+
\wedge & S' = S \with \STABLES[a] = \growtable(S.\STABLES[a], n, \val)) \\
598+
\end{array}
599+
\\[1ex]
600+
\begin{array}{lcl@{\qquad}l}
601+
S; F; (\I32.\CONST~n)~\TABLEGROW~x &\stepto& S; F; (\I32.\CONST~{-1})
602+
\end{array}
603+
\end{array}
604+
605+
.. note::
606+
The |TABLEGROW| instruction is non-deterministic.
607+
It may either succeed, returning the old table size :math:`\X{sz}`,
608+
or fail, returning :math:`{-1}`.
609+
Failure *must* occur if the referenced table instance has a maximum size defined that would be exceeded.
610+
However, failure *can* occur in other cases as well.
611+
In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.
612+
613+
614+
.. _exec-table.fill:
615+
616+
:math:`\TABLEFILL~x`
617+
....................
618+
619+
1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.
620+
621+
2. Assert: due to :ref:`validation <valid-table.fill>`, :math:`F.\AMODULE.\MITABLES[x]` exists.
622+
623+
3. Let :math:`a` be the :ref:`table address <syntax-tableaddr>` :math:`F.\AMODULE.\MITABLES[x]`.
624+
625+
4. Assert: due to :ref:`validation <valid-table.fill>`, :math:`S.\STABLES[a]` exists.
626+
627+
5. Let :math:`\X{tab}` be the :ref:`table instance <syntax-tableinst>` :math:`S.\STABLES[a]`.
628+
629+
6. Assert: due to :ref:`validation <valid-table.fill>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.
630+
631+
7. Pop the value :math:`\I32.\CONST~n` from the stack.
632+
633+
8. Assert: due to :ref:`validation <valid-table.fill>`, a :ref:`reference value <syntax-ref>` is on the top of the stack.
634+
635+
9. Pop the value :math:`\val` from the stack.
636+
637+
10. Assert: due to :ref:`validation <valid-table.fill>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.
638+
639+
11. Pop the value :math:`\I32.\CONST~i` from the stack.
640+
641+
12. If :math:`n` is :math:`0`, then:
642+
643+
a. If :math:`i` is larger than the length of :math:`\X{tab}.\TIELEM`, then:
644+
645+
i. Trap.
646+
647+
12. Else:
648+
649+
a. Push the value :math:`\I32.CONST~i` to the stack.
650+
651+
b. Push the value :math:`\val` to the stack.
652+
653+
c. Execute the instruction :math:`\TABLESET~x`.
654+
655+
d. Push the value :math:`\I32.CONST~(i+1)` to the stack.
656+
657+
e. Push the value :math:`\val` to the stack.
658+
659+
f. Push the value :math:`\I32.CONST~(n-1)` to the stack.
660+
661+
c. Execute the instruction :math:`\TABLEFILL~x`.
662+
663+
.. math::
664+
\begin{array}{l}
665+
\begin{array}{lcl@{\qquad}l}
666+
S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~(n+1))~(\TABLEFILL~x) &\stepto& S'; F; (\I32.\CONST~i)~\val~(\TABLESET~x)~(\I32.\CONST~(i+1))~\val~(\I32.\CONST~n)~(\TABLEFILL~x)
667+
\end{array} \\
668+
\begin{array}{lcl@{\qquad}l}
669+
S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~0)~(\TABLEFILL~x) &\stepto& S'; F; \epsilon
670+
\end{array}
671+
\\ \qquad
672+
(\iff i \leq |\STABLES[F.\AMODULE.\MITABLES[x]]|) \\
673+
\begin{array}{lcl@{\qquad}l}
674+
S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~0)~(\TABLEFILL~x) &\stepto& S; F; \TRAP
675+
\end{array}
676+
\\ \qquad
677+
(\otherwise) \\
678+
\end{array}
679+
680+
525681
.. index:: memory instruction, memory index, store, frame, address, memory address, memory instance, value, integer, limits, value type, bit width
526682
pair: execution; instruction
527683
single: abstract syntax; instruction

document/core/exec/modules.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ New instances of :ref:`functions <syntax-funcinst>`, :ref:`tables <syntax-tablei
298298
:ref:`Tables <syntax-tableinst>`
299299
................................
300300

301-
1. Let :math:`\tabletype` be the :ref:`table type <syntax-tabletype>` to allocate.
301+
1. Let :math:`\tabletype` be the :ref:`table type <syntax-tabletype>` to allocate and :math:`\val` the initialization value.
302302

303303
2. Let :math:`(\{\LMIN~n, \LMAX~m^?\}~\reftype)` be the structure of :ref:`table type <syntax-tabletype>` :math:`\tabletype`.
304304

@@ -312,11 +312,11 @@ New instances of :ref:`functions <syntax-funcinst>`, :ref:`tables <syntax-tablei
312312

313313
.. math::
314314
\begin{array}{rlll}
315-
\alloctable(S, \tabletype) &=& S', \tableaddr \\[1ex]
315+
\alloctable(S, \tabletype, \val) &=& S', \tableaddr \\[1ex]
316316
\mbox{where:} \hfill \\
317317
\tabletype &=& \{\LMIN~n, \LMAX~m^?\}~\reftype \\
318318
\tableaddr &=& |S.\STABLES| \\
319-
\tableinst &=& \{ \TIELEM~\REFNULL^n, \TIMAX~m^? \} \\
319+
\tableinst &=& \{ \TIELEM~\val^n, \TIMAX~m^? \} \\
320320
S' &=& S \compose \{\STABLES~\tableinst\} \\
321321
\end{array}
322322
@@ -385,7 +385,7 @@ New instances of :ref:`functions <syntax-funcinst>`, :ref:`tables <syntax-tablei
385385
Growing :ref:`tables <syntax-tableinst>`
386386
........................................
387387

388-
1. Let :math:`\tableinst` be the :ref:`table instance <syntax-tableinst>` to grow and :math:`n` the number of elements by which to grow it.
388+
1. Let :math:`\tableinst` be the :ref:`table instance <syntax-tableinst>` to grow, :math:`n` the number of elements by which to grow it, and :math:`\val` the initialization value.
389389

390390
2. Let :math:`\X{len}` be :math:`n` added to the length of :math:`\tableinst.\TIELEM`.
391391

@@ -397,7 +397,7 @@ Growing :ref:`tables <syntax-tableinst>`
397397

398398
.. math::
399399
\begin{array}{rllll}
400-
\growtable(\tableinst, n) &=& \tableinst \with \TIELEM = \tableinst.\TIELEM~\REFNULL^n \\
400+
\growtable(\tableinst, n, \val) &=& \tableinst \with \TIELEM = \tableinst.\TIELEM~\val^n \\
401401
&& (
402402
\begin{array}[t]{@{}r@{~}l@{}}
403403
\iff & \X{len} = n + |\tableinst.\TIELEM| \\
@@ -519,7 +519,7 @@ where:
519519
\MIEXPORTS~\exportinst^\ast ~\}
520520
\end{array} \\[1ex]
521521
S_1, \funcaddr^\ast &=& \allocfunc^\ast(S, \module.\MFUNCS, \moduleinst) \\
522-
S_2, \tableaddr^\ast &=& \alloctable^\ast(S_1, (\table.\TTYPE)^\ast)
522+
S_2, \tableaddr^\ast &=& \alloctable^\ast(S_1, (\table.\TTYPE)^\ast, \REFNULL)
523523
\qquad\qquad\qquad~ (\where \table^\ast = \module.\MTABLES) \\
524524
S_3, \memaddr^\ast &=& \allocmem^\ast(S_2, (\mem.\MTYPE)^\ast)
525525
\qquad\qquad\qquad~ (\where \mem^\ast = \module.\MMEMS) \\

document/core/syntax/instructions.rst

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ The |LOCALTEE| instruction is like |LOCALSET| but also returns its argument.
241241
pair: abstract syntax; instruction
242242
.. _syntax-table.get:
243243
.. _syntax-table.set:
244+
.. _syntax-table.size:
245+
.. _syntax-table.grow:
246+
.. _syntax-table.fill:
244247
.. _syntax-instr-table:
245248

246249
Table Instructions
@@ -253,10 +256,19 @@ Instructions in this group are concerned with accessing :ref:`tables <syntax-tab
253256
\production{instruction} & \instr &::=&
254257
\dots \\&&|&
255258
\TABLEGET~\tableidx \\&&|&
256-
\TABLESET~\tableidx \\
259+
\TABLESET~\tableidx \\&&|&
260+
\TABLESIZE~\tableidx \\&&|&
261+
\TABLEGROW~\tableidx \\&&|&
262+
\TABLEFILL~\tableidx \\
257263
\end{array}
258264
259-
These instructions get or set an element in a table, respectively.
265+
The |TABLEGET| and |TABLESET| instructions load or store an element in a table, respectively.
266+
267+
The |TABLESIZE| instruction returns the current size of a table.
268+
The |TABLEGROW| instruction grows table by a given delta and returns the previous size, or :math:`-1` if enough space cannot be allocated.
269+
It also takes an initialization value for the newly allocated entries.
270+
271+
The |TABLEFILL| instruction sets all entries in a range to a given value.
260272

261273
An additional instruction that accesses a table is the :ref:`control instruction <syntax-instr-control>` |CALLINDIRECT|.
262274

document/core/text/instructions.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,18 @@ Table Instructions
200200

201201
.. _text-table.get:
202202
.. _text-table.set:
203+
.. _text-table.size:
204+
.. _text-table.grow:
205+
.. _text-table.fill:
203206

204207
.. math::
205208
\begin{array}{llclll}
206209
\production{instruction} & \Tplaininstr_I &::=& \dots \\ &&|&
207210
\text{table.get}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEGET~x \\ &&|&
208-
\text{table.set}~~x{:}\Ttableidx_I &\Rightarrow& \TABLESET~x \\
211+
\text{table.set}~~x{:}\Ttableidx_I &\Rightarrow& \TABLESET~x \\ &&|&
212+
\text{table.size}~~x{:}\Ttableidx_I &\Rightarrow& \TABLESIZE~x \\ &&|&
213+
\text{table.grow}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEGROW~x \\ &&|&
214+
\text{table.fill}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEFILL~x \\
209215
\end{array}
210216
211217

document/core/util/macros.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@
328328

329329
.. |TABLEGET| mathdef:: \xref{syntax/instructions}{syntax-instr-table}{\K{table.get}}
330330
.. |TABLESET| mathdef:: \xref{syntax/instructions}{syntax-instr-table}{\K{table.set}}
331+
.. |TABLESIZE| mathdef:: \xref{syntax/instructions}{syntax-instr-table}{\K{table.size}}
332+
.. |TABLEGROW| mathdef:: \xref{syntax/instructions}{syntax-instr-table}{\K{table.grow}}
333+
.. |TABLEFILL| mathdef:: \xref{syntax/instructions}{syntax-instr-table}{\K{table.fill}}
331334

332335
.. |LOAD| mathdef:: \xref{syntax/instructions}{syntax-instr-memory}{\K{load}}
333336
.. |STORE| mathdef:: \xref{syntax/instructions}{syntax-instr-memory}{\K{store}}

0 commit comments

Comments
 (0)