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

[spec] Document execution #19

Closed
wants to merge 8 commits into from
Closed

[spec] Document execution #19

wants to merge 8 commits into from

Conversation

binji
Copy link
Member

@binji binji commented May 22, 2018

Started to work on spec for execution. Still more work to do, but I thought it would be useful to get some early feedback.

@binji binji requested a review from rossberg May 22, 2018 00:55
@binji
Copy link
Member Author

binji commented May 22, 2018

@binji
Copy link
Member Author

binji commented May 31, 2018

@rossberg PTAL if you have time!

Copy link
Member

@rossberg rossberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good, except for the correct indexing semantics.

One thing I was hoping for, though, is that with proper memory.init and table.init instructions we could get rid of the auxiliary init_data and init_elem ones, and replace their uses with the former. Is there a reason why that cannot work?


12. Pop the value :math:`\I32.\CONST~s` from the stack.

13. Pop the value :math:`\I32.\CONST~t` from the stack.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the spec convention is to use t for value types, and i,j,k,m,n for integers, at least if they are single-letter. So either use those or somewhat longer names.


a. Trap.

18. Let :math:`y` be the byte sequence :math:`\X{mem}.\DSIINIT[s \slice n]`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Use b^\ast instead of y.

\end{array}
\\[1ex]
\begin{array}{lcl@{\qquad}l}
S; F; (\I32.\CONST~n)~(\I32.\CONST~t)~(\I32.\CONST~s)~(\MEMORYINIT~x) &\stepto& S; F; \TRAP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs an "otherwise" as a side conditione, else it would always be allowed non-deterministically.


1. Let :math:`e` be the :ref:`element segment <syntax-elem>` to allocate.

2. If :math:`e` is of the form :math:`\{ \EINIT~x^\ast \}`, then:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this algorithm return otherwise? Should it be epsilon, i.e., the algo returns an optional address?

.. math::
\begin{array}{rlll@{\qquad}l}
\allocelem(S, e, \moduleinst) &=& S', \elemaddr & (\iff e = \{ \EINIT~x^\ast \}) \\[1ex]
\allocelem(S, e, \moduleinst) &=& S & (\otherwise) \\[1ex]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only returns one thing, not a pair, which seems incoherent. I think it should be epsilon.


1. Let :math:`d` be the :ref:`data segment <syntax-data>` to allocate.

2. If :math:`d` is of the form :math:`\{ \DINIT~b^\ast \}`, then:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

6. Let :math:`\funcaddr^\ast` be the the concatenation of the :ref:`function addresses <syntax-funcaddr>` :math:`\funcaddr_i` in index order.
6. For each :ref:`element segment <syntax-elem>` :math:`\elem_i` in :math:`\module.\MELEM`, do:

a. Let :math:`\elemaddr_i` be the :ref:`element address <syntax-elemaddr>` resulting from :ref:`allocating <alloc-elem>` :math:`\elem_i` for the :ref:`\module instance <syntax-moduleinst>` :math:`\moduleinst` defined below.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you assume that the vector of elemaddr_i corresponds to elem_i, which is not the case because you only get addresses for passive elements. So I think what the module instance needs to store is not am elemaddr^* but an (elemaddr^?)^*. Otherwise all the indexing will be off, too.

@@ -158,6 +170,8 @@ and collects runtime representations of all entities that are imported, defined,
\MITABLES & \tableaddr^\ast, \\
\MIMEMS & \memaddr^\ast, \\
\MIGLOBALS & \globaladdr^\ast, \\
\MIELEMS & \elemaddr^\ast, \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I think these need to be optional addresses to represent indices of active segments correctly.

.. math::
\begin{array}{llll}
\production{(element instance)} & \eleminst &::=&
\{ \ESIINIT~\vec(\funcaddr) \} \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: why not EIINIT?

.. math::
\begin{array}{llll}
\production{(data instance)} & \datainst &::=&
\{ \DSIINIT~\vec(\byte) \} \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same Q here.

@binji
Copy link
Member Author

binji commented Jun 7, 2018

One thing I was hoping for, though, is that with proper memory.init and table.init instructions we could get rid of the auxiliary init_data and init_elem ones, and replace their uses with the former. Is there a reason why that cannot work?

I think it's possible, and I started to do this, but it's pretty ugly unless we go with option 2 here.

Here's what I was thinking:

  • Create element/data instances for all segments, even active ones
  • instantiate executes something like S;F; (i32.const |elem.data|) (i32.const 0) (elem.offset) (table.init x) (table.drop x) for each active segment
  • Similar for data segments

Without option 2, though, I guess you'd need to conditionally update the state only if none of the instructions trap. I started to write this, but wasn't quite sure how to define it, and thought we may need to change it for the threads proposal anyway.

@rossberg
Copy link
Member

rossberg commented Jun 9, 2018

Yes, I like that makes. Look slike the preferable route.

For option 1, wouldn't the only difference be that we keep the bounds checks as pre-checks in the instantiation itself?

Copy link
Member

@rossberg rossberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, dropped the ball on this review.

\end{array}
\\ \qquad
\begin{array}[j]{@{}r@{~}l@{}}
(\iff & F.\AMODULE.\MIMEMS[0] = ma \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like ma isn't needed (similarly in prose).

~\\[-1ex]
\begin{array}{l}
\begin{array}{lcl@{\qquad}l}
S; F; (\I32.\CONST~n)~(\I32.\CONST~j)~(\I32.\CONST~i)~(\MEMORYCOPY~x) &\stepto& S; F; (\INITDATA~ma~j~b^\ast)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The index x seems unused. I think in the future we will want two indices, for source and target memory, but for now we can probably drop both from the AST.

(\iff & F.\AMODULE.\MIMEMS[0] = ma \\
\wedge & (i + n \leq |S.\SMEMS[ma].\MIDATA|) \\
\wedge & (j + n \leq |S.\SMEMS[ma].\MIDATA|) \\
\wedge & b^\ast = S.\SMEMS[ma].\MIDATA[i \slice n]) \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a note that this semantics implies that overlapping ranges are handled correctly?

Also, this semantics essentially prescribes buffering of the copied memory before writing begins. That will be observable once we have threads and concurrent mutation. I think it's fine to leave this for now, but I suspect we will need to tweak it. Perhaps adda TODO note?


8. Let :math:`ea` be the :ref:`element segment address <syntax-elemaddr>` :math:`F.\AMODULE.\MIELEMS[x]`.

9. If :math:`S.\SELEM[ea]` does not exist, then:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: better say "is unset" or something like that (ea exists in the list, but its value is epsilon).

\end{array}
\\ \qquad
\begin{array}[j]{@{}r@{~}l@{}}
(\iff & F.\AMODULE.\MITABLES[0] = ta \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: ta is unused.

~\\[-1ex]
\begin{array}{l}
\begin{array}{lcl@{\qquad}l}
S; F; (\I32.\CONST~n)~(\I32.\CONST~j)~(\I32.\CONST~i)~(\TABLECOPY~x) &\stepto& S; F; (\INITELEM~ta~j~y^\ast)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: x unused.

.. index:: table, table instance, table address, initialize table
.. _initelem:

:math:`\INITELEM~\tableaddr~o~x^\ast`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename x* to a* here and below, since they're not function indices but function addresses.


b. For each :ref:`function index <syntax-funcidx>` :math:`x_i` in :math:`e.\EINIT`, do:
a. Let :math:`\funcaddr_i` be the :ref:`function address <syntax-funcaddr>` :math:`\moduleinst.\MIFUNCS[x_i]`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First assert that this exists.

\begin{array}[j]{@{}r@{~}l@{}}
(\iff & F.\AMODULE.\MIMEMS[0] = ma \\
\wedge & F.\AMODULE.\MIDATAS[x] = da \\
\wedge & S' = S \with \SDATA[da] = \epsilon) \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a SDATA slot to epsilon must allow for it in the definition of store, i.e., change the syntax to (\datainst^?)^* (same for element segments).

@binji
Copy link
Member Author

binji commented Jul 9, 2018

Sorry, dropped the ball on this review.

It's OK, I still haven't fixed the instantiation to use MEMORYINIT/TABLEINIT instead of INITDATA/INITELEM. Got a bit sidetracked with other stuff.

@binji
Copy link
Member Author

binji commented Feb 21, 2019

This is pretty out-of-date at this point, closing for now.

@binji binji closed this Feb 21, 2019
binji added a commit that referenced this pull request May 24, 2019
This is copied and modified from this closed PR:

#19
binji added a commit that referenced this pull request May 31, 2019
This is copied and modified from this closed PR:

#19
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants