diff --git a/README.md b/README.md index 1b036fc..a029f5e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ add support for <> to WebAssembly. * See the [overview](proposals/profiles/Overview.md) for a summary of the proposal. -* See the [modified spec](https://webassembly.github.io/profiles/) for details (TODO). +* See the [modified spec](https://webassembly.github.io/profiles/) for details. Original `README` from upstream repository follows... diff --git a/document/core/appendix/index.rst b/document/core/appendix/index.rst index c4173e9..bf66222 100644 --- a/document/core/appendix/index.rst +++ b/document/core/appendix/index.rst @@ -7,6 +7,7 @@ Appendix :maxdepth: 2 embedding + profiles implementation algorithm custom diff --git a/document/core/appendix/profiles.rst b/document/core/appendix/profiles.rst new file mode 100644 index 0000000..8d36083 --- /dev/null +++ b/document/core/appendix/profiles.rst @@ -0,0 +1,129 @@ +.. index:: ! profile, abstract syntax, validation, execution, binary format, text format +.. _profiles: + +Profiles +-------- + +To enable the use of WebAssembly in as many environments as possible, *profiles* specify coherent language subsets that fit constraints imposed by common classes of host environments. +A host platform can thereby decide to support the language only under a restricted profile, or even the intersection of multiple profiles. + + +Conventions +~~~~~~~~~~~ + +A profile modification is specified by decorating selected rules in the main body of this specification with a *profile annotation* that defines them as "conditional" on the choice of profile. + +For that purpose, every profile defines a *profile marker*, an alphanumeric short-hand like :math:`\profilename{ABC}`. +A profile annotation of the form :math:`\exprofiles{\profile{ABC}~\profile{XYZ}}` on a rule indicates that this rule is *excluded* for either of the profiles whose marker is :math:`\profilename{ABC}` or :math:`\profilename{XYZ}`. + +There are two ways of subsetting the language in a profile: + +* *Syntactic*, by *omitting* a feature, in which case certain constructs are removed from the syntax altogether. + +* *Semantic*, by *restricting* a feature, in which case certain constructs are still present but some behaviours are ruled out. + + +Syntax Annotations +.................. + +To omit a construct from a profile syntactically, respective productions in the grammar of the :ref:`abstract syntax ` are annotated with an associated profile marker. +This is defined to have the following implications: + +1. Any production in the :ref:`binary ` or :ref:`textual ` syntax that produces abstract syntax with a marked construct is omitted by extension. + +2. Any :ref:`validation ` or :ref:`execution ` rule that handles a marked construct is omitted by extension. + +The overall effect is that the respective construct is no longer part of the language under a respective profile. + +.. note:: + For example, a "busy" profile marked :math:`\profilename{BUSY}` could rule out the |NOP| instruction by marking the production for it in the abstract syntax as follows: + + .. math:: + \begin{array}{llcl} + \production{instruction} & \instr &::=& + \dots \\ + & \exprofiles{\profile{BUSY}} &|& \NOP \\ + & &|& \UNREACHABLE \\ + \end{array} + + A rule may be annotated by multiple markers, which might be the case if a construct is in the intersection of multiple features. + + +Semantics Annotations +..................... + +To restrict certain behaviours in a profile, individual :ref:`validation ` or :ref:`reduction ` rules or auxiliary definitions are annotated with an associated marker. + +This has the simple consequence that the respective rule is no longer applicable under the given profile. + +.. note:: + For example, an "infinite" profile marked :math:`\profilename{INF}` could define that growing memory never fails: + + .. math:: + \begin{array}{llcl@{\qquad}l} + & S; F; (\I32.\CONST~n)~\MEMORYGROW &\stepto& S'; F; (\I32.\CONST~\X{sz}) + \\&&& + \begin{array}[t]{@{}r@{~}l@{}} + (\iff & F.\AMODULE.\MIMEMS[0] = a \\ + \wedge & \X{sz} = |S.\SMEMS[a].\MIDATA|/64\,\F{Ki} \\ + \wedge & S' = S \with \SMEMS[a] = \growmem(S.\SMEMS[a], n)) \\[1ex] + \end{array} + \\[1ex] + \exprofiles{\profile{INF}} & S; F; (\I32.\CONST~n)~\MEMORYGROW &\stepto& S; F; (\I32.\CONST~\signed_{32}^{-1}(-1)) + \end{array} + + +Properties +.......... + +All profiles are defined such that the following properties are preserved: + +* All profiles represent syntactic and semantic subsets of the :ref:`full profile `, i.e., they do not *add* syntax or *alter* behaviour. + +* All profiles are mutually compatible, i.e., no two profiles subset semantic behaviour in inconsistent ways, and any intersection of profiles preserves the properties described here. + +* Profiles that restrict execution do not violate :ref:`soundness `, i.e., all :ref:`configurations ` valid under that profile still have well-defined execution behaviour. + +.. note:: + Tools are generally expected to handle and produce code for the full profile by default. + In particular, producers should not generate code that *depends* on specific profiles. Instead, all code should preserve correctness when executed under the full profile. + + Moreover, profiles should be considered static and fixed for a given platform or ecosystem. Runtime conditioning on the "current" profile should especially be avoided. + + + +Defined Profiles +~~~~~~~~~~~~~~~~ + +.. note:: + The number of defined profiles is expected to remain small in the future. Profiles are intended for broad and permanent use cases only. In particular, profiles are not intended for language versioning. + + +.. index:: full profile + single: profile; full +.. _profile-full: + +Full Profile (:math:`{\small{\mathrm{FUL}}}`) +............................................. + +The *full* profile contains the complete language and all possible behaviours. +It imposes no restrictions, i.e., all rules and definitions are active. +All other profiles define sub-languages of this profile. + + +.. index:: determinism, non-determinism, deterministic profile + single: profile; deterministic +.. _profile-deterministic: + +Deterministic Profile (:math:`{\small{\mathrm{DET}}}`) +...................................................... + +The *deterministic* profile excludes all rules marked :math:`\exprofiles{\PROFDET}`. +It defines a sub-language that does not exhibit any incidental non-deterministic behaviour: + +* All :ref:`NaN ` values :ref:`generated ` by :ref:`floating-point instructions ` are canonical and positive. + +Even under this profile, the |MEMORYGROW| and |TABLEGROW| instructions technically remain :ref:`non-deterministic `, in order to be able to indicate resource exhaustion. + +.. note:: + In future versions of WebAssembly, new non-deterministic behaviour may be added to the language, such that the deterministic profile will induce additional restrictions. diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index 6b02806..599e81f 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -7,7 +7,7 @@ Instructions WebAssembly computation is performed by executing individual :ref:`instructions `. -.. index:: numeric instruction, determinism, trap, NaN, value, value type +.. index:: numeric instruction, determinism, non-determinism, trap, NaN, value, value type pair: execution; instruction single: abstract syntax; instruction .. _exec-instr-numeric: @@ -1263,6 +1263,7 @@ Table Instructions \end{array} +.. index:: determinism, non-determinism .. _exec-table.grow: :math:`\TABLEGROW~x` @@ -2129,6 +2130,7 @@ Memory Instructions \end{array} +.. index:: determinism, non-determinism .. _exec-memory.grow: :math:`\MEMORYGROW` diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index 71dfef6..868ca10 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -1,4 +1,4 @@ -.. index:: value, integer, floating-point, bit width, determinism, NaN +.. index:: value, integer, floating-point, bit width, determinism, non-determinism, NaN .. _exec-op-partial: .. _exec-numeric: @@ -1025,7 +1025,7 @@ where: \end{array} -.. index:: NaN +.. index:: NaN, determinism, non-determinism .. _aux-nans: NaN Propagation @@ -1038,14 +1038,17 @@ then its sign is non-deterministic and the :ref:`payload ` is co * Otherwise the payload is picked non-deterministically among all :ref:`arithmetic NaNs `; that is, its most significant bit is :math:`1` and all others are unspecified. +* In the :ref:`deterministic profile `, only positive canonical NaN outputs are produced. + This non-deterministic result is expressed by the following auxiliary function producing a set of allowed outputs from a set of inputs: .. math:: - \begin{array}{lll@{\qquad}l} - \nans_N\{z^\ast\} &=& \{ + \NAN(n), - \NAN(n) ~|~ n = \canon_N \} - & (\iff \forall \NAN(n) \in z^\ast,~ n = \canon_N) \\ - \nans_N\{z^\ast\} &=& \{ + \NAN(n), - \NAN(n) ~|~ n \geq \canon_N \} - & (\otherwise) \\ + \begin{array}{llcl@{\qquad}l} + & \nans_N\{z^\ast\} &=& \{ + \NAN(\canon_N) \} \\ + \exprofiles{\PROFDET} & \nans_N\{z^\ast\} &=& \{ + \NAN(n), - \NAN(n) ~|~ n = \canon_N \} + & (\iff \forall \,{\pm \NAN(n)} \in z^\ast,~ n = \canon_N) \\ + \exprofiles{\PROFDET} & \nans_N\{z^\ast\} &=& \{ + \NAN(n), - \NAN(n) ~|~ n \geq \canon_N \} + & (\iff \exists \,{\pm \NAN(n)} \in z^\ast,~ n \neq \canon_N) \\ \end{array} diff --git a/document/core/util/bikeshed_fixup.py b/document/core/util/bikeshed_fixup.py index dcd4fd0..6cfdaa2 100755 --- a/document/core/util/bikeshed_fixup.py +++ b/document/core/util/bikeshed_fixup.py @@ -22,10 +22,12 @@ def Main(): number = 1 for section in [ 'Embedding', + 'Profiles', 'Implementation Limitations', 'Validation Algorithm', 'Custom Sections', 'Soundness', + 'Changes', 'Index of Types', 'Index of Instructions', 'Index of Semantic Rules']: diff --git a/document/core/util/macros.def b/document/core/util/macros.def index aaefc40..06b5455 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -108,6 +108,16 @@ .. |bigcompose| mathdef:: \xref{syntax/conventions}{notation-compose}{\bigoplus} +.. Notation for Profiles + +.. |exprofiles#1| mathdef:: {^{\small{[!#1]}}} +.. |profilename#1| mathdef:: {\small{\mathrm{#1}}} +.. |profile| mathdef:: \mathrm + +.. |PROFFULL| mathdef:: \xref{appendix/profiles}{profile-full}{\profile{FUL}} +.. |PROFDET| mathdef:: \xref{appendix/profiles}{profile-deterministic}{\profile{DET}} + + .. Abstract Syntax .. ---------------