Repository: WebAssembly/reference-types Branch: master Commit: c7a3558bb5cb Files: 321 Total size: 4.9 MB Directory structure: gitextract_qmxq1s8y/ ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .travis.yml ├── Contributing.md ├── LICENSE ├── README.md ├── deploy_key.enc ├── document/ │ ├── Makefile │ ├── README.md │ ├── core/ │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── appendix/ │ │ │ ├── algorithm.rst │ │ │ ├── custom.rst │ │ │ ├── embedding.rst │ │ │ ├── gen-index-instructions.py │ │ │ ├── implementation.rst │ │ │ ├── index-instructions.rst │ │ │ ├── index-rules.rst │ │ │ ├── index-types.rst │ │ │ ├── index.rst │ │ │ └── properties.rst │ │ ├── binary/ │ │ │ ├── conventions.rst │ │ │ ├── index.rst │ │ │ ├── instructions.rst │ │ │ ├── modules.rst │ │ │ ├── types.rst │ │ │ └── values.rst │ │ ├── conf.py │ │ ├── exec/ │ │ │ ├── conventions.rst │ │ │ ├── index.rst │ │ │ ├── instructions.rst │ │ │ ├── modules.rst │ │ │ ├── numerics.rst │ │ │ └── runtime.rst │ │ ├── index.bs │ │ ├── index.rst │ │ ├── intro/ │ │ │ ├── index.rst │ │ │ ├── introduction.rst │ │ │ └── overview.rst │ │ ├── make.bat │ │ ├── static/ │ │ │ └── custom.css │ │ ├── syntax/ │ │ │ ├── conventions.rst │ │ │ ├── index.rst │ │ │ ├── instructions.rst │ │ │ ├── modules.rst │ │ │ ├── types.rst │ │ │ └── values.rst │ │ ├── text/ │ │ │ ├── conventions.rst │ │ │ ├── index.rst │ │ │ ├── instructions.rst │ │ │ ├── lexical.rst │ │ │ ├── modules.rst │ │ │ ├── types.rst │ │ │ └── values.rst │ │ ├── util/ │ │ │ ├── README.htmldiff.pl │ │ │ ├── bikeshed/ │ │ │ │ └── conf.py │ │ │ ├── bikeshed_fixup.py │ │ │ ├── katex_fix.patch │ │ │ ├── macros.def │ │ │ ├── mathdef.py │ │ │ ├── mathdefbs.py │ │ │ ├── mathjax2katex.py │ │ │ └── pseudo-lexer.py │ │ └── valid/ │ │ ├── conventions.rst │ │ ├── index.rst │ │ ├── instructions.rst │ │ ├── modules.rst │ │ └── types.rst │ ├── deploy.sh │ ├── index.html │ ├── js-api/ │ │ ├── Makefile │ │ └── index.bs │ ├── travis-deploy.sh │ ├── util/ │ │ └── htmldiff.pl │ └── web-api/ │ ├── Makefile │ └── index.bs ├── interpreter/ │ ├── .gitignore │ ├── .merlin │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── binary/ │ │ ├── decode.ml │ │ ├── decode.mli │ │ ├── encode.ml │ │ ├── encode.mli │ │ ├── utf8.ml │ │ └── utf8.mli │ ├── exec/ │ │ ├── eval.ml │ │ ├── eval.mli │ │ ├── eval_numeric.ml │ │ ├── eval_numeric.mli │ │ ├── f32.ml │ │ ├── f32_convert.ml │ │ ├── f32_convert.mli │ │ ├── f64.ml │ │ ├── f64_convert.ml │ │ ├── f64_convert.mli │ │ ├── float.ml │ │ ├── i32.ml │ │ ├── i32_convert.ml │ │ ├── i32_convert.mli │ │ ├── i64.ml │ │ ├── i64_convert.ml │ │ ├── i64_convert.mli │ │ ├── int.ml │ │ └── numeric_error.ml │ ├── host/ │ │ ├── env.ml │ │ └── spectest.ml │ ├── main/ │ │ ├── flags.ml │ │ └── main.ml │ ├── meta/ │ │ ├── findlib/ │ │ │ └── META │ │ ├── jslib/ │ │ │ ├── bsconfig.json │ │ │ ├── build.sh │ │ │ └── wasm.ml │ │ └── travis/ │ │ ├── build-test.sh │ │ └── install-ocaml.sh │ ├── runtime/ │ │ ├── func.ml │ │ ├── func.mli │ │ ├── global.ml │ │ ├── global.mli │ │ ├── instance.ml │ │ ├── memory.ml │ │ ├── memory.mli │ │ ├── table.ml │ │ └── table.mli │ ├── script/ │ │ ├── import.ml │ │ ├── import.mli │ │ ├── js.ml │ │ ├── js.mli │ │ ├── run.ml │ │ ├── run.mli │ │ └── script.ml │ ├── syntax/ │ │ ├── ast.ml │ │ ├── free.ml │ │ ├── free.mli │ │ ├── operators.ml │ │ ├── types.ml │ │ └── values.ml │ ├── text/ │ │ ├── arrange.ml │ │ ├── arrange.mli │ │ ├── lexer.mli │ │ ├── lexer.mll │ │ ├── parse.ml │ │ ├── parse.mli │ │ ├── parser.mly │ │ ├── print.ml │ │ └── print.mli │ ├── util/ │ │ ├── error.ml │ │ ├── error.mli │ │ ├── lib.ml │ │ ├── lib.mli │ │ ├── sexpr.ml │ │ ├── sexpr.mli │ │ ├── source.ml │ │ └── source.mli │ ├── valid/ │ │ ├── valid.ml │ │ └── valid.mli │ └── winmake.bat ├── papers/ │ ├── LICENSE │ └── README.md ├── proposals/ │ ├── README.md │ ├── bulk-memory-operations/ │ │ └── Overview.md │ ├── multi-value/ │ │ └── Overview.md │ ├── nontrapping-float-to-int-conversion/ │ │ └── Overview.md │ ├── reference-types/ │ │ └── Overview.md │ └── sign-extension-ops/ │ └── Overview.md ├── test/ │ ├── LICENSE │ ├── README.md │ ├── Todo.md │ ├── build.py │ ├── core/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── address.wast │ │ ├── align.wast │ │ ├── binary-leb128.wast │ │ ├── binary.wast │ │ ├── block.wast │ │ ├── br.wast │ │ ├── br_if.wast │ │ ├── br_table.wast │ │ ├── bulk.wast │ │ ├── call.wast │ │ ├── call_indirect.wast │ │ ├── comments.wast │ │ ├── const.wast │ │ ├── conversions.wast │ │ ├── custom.wast │ │ ├── data.wast │ │ ├── elem.wast │ │ ├── endianness.wast │ │ ├── exports.wast │ │ ├── f32.wast │ │ ├── f32_bitwise.wast │ │ ├── f32_cmp.wast │ │ ├── f64.wast │ │ ├── f64_bitwise.wast │ │ ├── f64_cmp.wast │ │ ├── fac.wast │ │ ├── float_exprs.wast │ │ ├── float_literals.wast │ │ ├── float_memory.wast │ │ ├── float_misc.wast │ │ ├── forward.wast │ │ ├── func.wast │ │ ├── func_ptrs.wast │ │ ├── global.wast │ │ ├── i32.wast │ │ ├── i64.wast │ │ ├── if.wast │ │ ├── imports.wast │ │ ├── inline-module.wast │ │ ├── int_exprs.wast │ │ ├── int_literals.wast │ │ ├── labels.wast │ │ ├── left-to-right.wast │ │ ├── linking.wast │ │ ├── load.wast │ │ ├── local_get.wast │ │ ├── local_set.wast │ │ ├── local_tee.wast │ │ ├── loop.wast │ │ ├── memory.wast │ │ ├── memory_copy.wast │ │ ├── memory_fill.wast │ │ ├── memory_grow.wast │ │ ├── memory_init.wast │ │ ├── memory_redundancy.wast │ │ ├── memory_size.wast │ │ ├── memory_trap.wast │ │ ├── names.wast │ │ ├── nop.wast │ │ ├── ref_func.wast │ │ ├── ref_is_null.wast │ │ ├── ref_null.wast │ │ ├── return.wast │ │ ├── run.py │ │ ├── select.wast │ │ ├── skip-stack-guard-page.wast │ │ ├── stack.wast │ │ ├── start.wast │ │ ├── store.wast │ │ ├── switch.wast │ │ ├── table-sub.wast │ │ ├── table.wast │ │ ├── table_copy.wast │ │ ├── table_fill.wast │ │ ├── table_get.wast │ │ ├── table_grow.wast │ │ ├── table_init.wast │ │ ├── table_set.wast │ │ ├── table_size.wast │ │ ├── token.wast │ │ ├── traps.wast │ │ ├── type.wast │ │ ├── unreachable.wast │ │ ├── unreached-invalid.wast │ │ ├── unwind.wast │ │ ├── utf8-custom-section-id.wast │ │ ├── utf8-import-field.wast │ │ ├── utf8-import-module.wast │ │ └── utf8-invalid-encoding.wast │ ├── harness/ │ │ ├── async_index.js │ │ ├── sync_index.js │ │ ├── testharness.css │ │ ├── testharness.js │ │ └── testharnessreport.js │ ├── js-api/ │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── assertions.js │ │ ├── bad-imports.js │ │ ├── constructor/ │ │ │ ├── compile.any.js │ │ │ ├── instantiate-bad-imports.any.js │ │ │ ├── instantiate.any.js │ │ │ ├── multi-value.any.js │ │ │ └── validate.any.js │ │ ├── error-interfaces-no-symbol-tostringtag.js │ │ ├── global/ │ │ │ ├── constructor.any.js │ │ │ ├── toString.any.js │ │ │ ├── value-get-set.any.js │ │ │ └── valueOf.any.js │ │ ├── instance/ │ │ │ ├── constructor-bad-imports.any.js │ │ │ ├── constructor-caching.any.js │ │ │ ├── constructor.any.js │ │ │ ├── exports.any.js │ │ │ └── toString.any.js │ │ ├── instanceTestFactory.js │ │ ├── interface.any.js │ │ ├── limits.any.js │ │ ├── memory/ │ │ │ ├── assertions.js │ │ │ ├── buffer.any.js │ │ │ ├── constructor.any.js │ │ │ ├── grow.any.js │ │ │ └── toString.any.js │ │ ├── module/ │ │ │ ├── constructor.any.js │ │ │ ├── customSections.any.js │ │ │ ├── exports.any.js │ │ │ ├── imports.any.js │ │ │ └── toString.any.js │ │ ├── prototypes.any.js │ │ ├── table/ │ │ │ ├── assertions.js │ │ │ ├── constructor.any.js │ │ │ ├── get-set.any.js │ │ │ ├── grow.any.js │ │ │ ├── length.any.js │ │ │ └── toString.any.js │ │ └── wasm-module-builder.js │ ├── meta/ │ │ ├── Makefile │ │ ├── README.md │ │ ├── common.js │ │ ├── generate_memory_copy.js │ │ ├── generate_memory_fill.js │ │ ├── generate_memory_init.js │ │ ├── generate_table_copy.js │ │ ├── generate_table_init.js │ │ └── noderun.sh │ └── sync-js-api.py ├── w3c.json └── wasm-specs.bib ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.rst linguist-documentation=false document/* linguist-documentation=false document/*.rst linguist-documentation=false document/*/*.rst linguist-documentation=false test/harness/wast.js linguist-vendored test/harness/testharness* linguist-vendored ================================================ FILE: .gitignore ================================================ **/*~ **/*.tmproj **/*.pyc **/_build **/_output ================================================ FILE: .gitmodules ================================================ [submodule "document/core/util/katex"] path = document/core/util/katex url = https://github.com/KaTeX/KaTeX.git ================================================ FILE: .travis.yml ================================================ language: python python: - "3.7" dist: bionic addons: apt: sources: - sourceline: 'ppa:avsm/ppa' - sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main' key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg' update: true packages: - opam - texlive-full - yarn install: - opam init --auto-setup --compiler=4.07.1 - eval $(opam env) - opam --version - ocaml --version - opam install --yes ocamlbuild.0.14.0 - pip install Sphinx==2.4.4 - git clone https://github.com/tabatkins/bikeshed.git - pip install --editable $PWD/bikeshed - bikeshed update script: - ./interpreter/meta/travis/build-test.sh - bash ./document/travis-deploy.sh os: linux env: global: - ENCRYPTION_LABEL: "5d9ec396f41d" - COMMIT_AUTHOR_EMAIL: "noreply@webassembly.org" ================================================ FILE: Contributing.md ================================================ # Contributing to WebAssembly Interested in participating? Please follow [the same contributing guidelines as the design repository][]. [the same contributing guidelines as the design repository]: https://github.com/WebAssembly/design/blob/master/Contributing.md Also, please be sure to read [the README.md](README.md) for this repository. ================================================ FILE: LICENSE ================================================ Please see the LICENSE file in each top-level directory for the terms applicable to that directory and its relative sub-directories. The relevant directories and licenses are: document/ - W3C Software and Document Notice and License interpreter/ - Apache License 2.0 test/ - Apache License 2.0 papers/ - Creative Commons Attribution 4.0 International License ================================================ FILE: README.md ================================================ [![Build Status](https://travis-ci.org/WebAssembly/reference-types.svg?branch=master)](https://travis-ci.org/WebAssembly/reference-types) # Reference Types Proposal for WebAssembly This repository is a clone of [github.com/WebAssembly/spec/](https://github.com/WebAssembly/spec/). It is meant for discussion, prototype specification and implementation of a proposal to add support for basic reference types to WebAssembly. * See the [overview](proposals/reference-types/Overview.md) for a summary of the proposal. * See the [modified spec](https://webassembly.github.io/reference-types/core/) for details. The repository is now based on the [bulk operations proposal](proposals/bulk-memory-operations/Overview.md) and includes all respective changes. Original README from upstream repository follows... # spec This repository holds a prototypical reference implementation for WebAssembly, which is currently serving as the official specification. Eventually, we expect to produce a specification either written in human-readable prose or in a formal specification language. It also holds the WebAssembly testsuite, which tests numerous aspects of conformance to the spec. View the work-in-progress spec at [webassembly.github.io/spec](https://webassembly.github.io/spec/). At this time, the contents of this repository are under development and known to be "incomplet and inkorrect". Participation is welcome. Discussions about new features, significant semantic changes, or any specification change likely to generate substantial discussion should take place in [the WebAssembly design repository](https://github.com/WebAssembly/design) first, so that this spec repository can remain focused. And please follow the [guidelines for contributing](Contributing.md). # citing For citing WebAssembly in LaTeX, use [this bibtex file](wasm-specs.bib). ================================================ FILE: document/Makefile ================================================ DIRS = core js-api web-api FILES = index.html BUILDDIR = _build # Global targets. .PHONY: all all: $(BUILDDIR) root $(DIRS) $(BUILDDIR): mkdir -p $@ .PHONY: deploy deploy: GIT_DEPLOY_DIR=$(BUILDDIR) bash deploy.sh .PHONY: publish publish: all deploy .PHONY: clean clean: $(DIRS:%=clean-%) rm -rf $(BUILDDIR) .PHONY: diff diff: $(DIRS:%=diff-%) # Directory-specific targets. .PHONY: root root: $(BUILDDIR) touch $(BUILDDIR)/.nojekyll cp -f $(FILES) $(BUILDDIR)/ .PHONY: $(DIRS) $(DIRS): %: $(BUILDDIR) $(DIRS:%=build-%) $(DIRS:%=dir-%) .PHONY: $(DIRS:%=build-%) $(DIRS:%=build-%): build-%: (cd $(@:build-%=%); make BUILDDIR=$(BUILDDIR) all) .PHONY: $(DIRS:%=dir-%) $(DIRS:%=dir-%): dir-%: mkdir -p $(BUILDDIR)/$(@:dir-%=%) rm -rf $(BUILDDIR)/$(@:dir-%=%)/* cp -R $(@:dir-%=%)/$(BUILDDIR)/html/* $(BUILDDIR)/$(@:dir-%=%)/ .PHONY: $(DIRS:%=deploy-%) $(DIRS:%=deploy-%): deploy-%: GIT_DEPLOY_DIR=$(BUILDDIR) GIT_DEPLOY_SUBDIR=$(@:deploy-%=%) bash deploy.sh .PHONY: $(DIRS:%=publish-%) $(DIRS:%=publish-%): publish-%: % deploy-% .PHONY: $(DIRS:%=clean-%) $(DIRS:%=clean-%): clean-%: (cd $(@:clean-%=%); make BUILDDIR=$(BUILDDIR) clean) rm -rf $(BUILDDIR)/$(@:clean-%=%) .PHONY: $(DIRS:%=diff-%) $(DIRS:%=diff-%): diff-%: (cd $(@:diff-%=%); make BUILDDIR=$(BUILDDIR) diff) # Help. .PHONY: help help: @echo "Please use \`make ' where is one of" @echo " all to build all documents" @echo " publish to make all and push to gh-pages" @echo " to build a specific subdirectory" @echo " publish- to build and push a specific subdirectory" .PHONY: usage usage: help ================================================ FILE: document/README.md ================================================ # WebAssembly Specifications This directory contains the source code for the WebAssembly spec documents, as served from the [webassembly.github.io/spec](https://webassembly.github.io/spec) pages. It uses [Sphinx](http://www.sphinx-doc.org/) and [Bikeshed](https://github.com/tabatkins/bikeshed). To install Sphinx: ``` pip install sphinx ``` To install Bikeshed, see the instructions [here](https://tabatkins.github.io/bikeshed/#installing). To build everything locally (result appears in `_build/`): ``` make all ``` To build everything and update [webassembly.github.io/spec](https://webassembly.github.io/spec) with it: ``` make publish ``` Please make sure to only use that once a change has approval. ## Step by step guide to building the spec ### Prerequisites You will need `python3.7`, and `pip`. `pip` should come with Python, if not follow [these installation instructions for `pip`](https://pip.pypa.io/en/stable/installing/), or check your system package manager for `pip3`. > Important: you will need the version of pip that works with `python3.7`. Use something like [`pipenv`](https://pipenv.pypa.io/) to keep your system installation of Python clean. ``` pip install pipenv pipenv --python 3.7 pipenv shell ``` Install Python dependencies: ``` pip install Sphinx==2.4.4 ``` ### Checking out the repository Make sure this repository was cloned with `--recursive`: ``` git clone --recursive https://github.com/WebAssembly/spec ``` If you have already cloned but without `--recursive`, you can delete and re-clone, or `cd` into `spec` and run: ``` git submodule update --init --recursive ``` The rest of these instructions assume you are in the directory where is README is: ``` cd spec/document ``` ### Building the multi-page HTML document You can now build the [multi-page html document](https://webassembly.github.io/spec/core/): ``` make -C core html ``` ### Building the single-page HTML document To build the [single-page W3C version](https://webassembly.github.io/spec/core/bikeshed/), there are more dependencies to install. First, get [Bikeshed](https://github.com/tabatkins/bikeshed): ``` # cd back to root of git directory git clone https://github.com/tabatkins/bikeshed.git pip install --editable bikeshed bikeshed update ``` You will also need `npm` and `yarn` for all the LaTeX goodness. `npm` might already be available on your system, you can also use something like [`nvm`](https://github.com/nvm-sh/nvm) to prevent messing with system packages: ``` npm install -g yarn cd document make -C core bikeshed ``` ### Building the PDF To build the [PDF](https://webassembly.github.io/spec/core/_download/WebAssembly.pdf), you will need `texlive-full`, install it using your system package manager: ``` apt install texlive-full make -C core pdf ``` ### Building the JavaScript Embedding API To build the [JavaScript Embedding API](https://webassembly.github.io/spec/js-api/index.html), you will need `bikeshed` as describe in the section [Building the single-page HTML document](#building-the-single-page-html-document): ``` make -C js-api ``` ### Building the Web Embedding API To build the [Web Embedding API](https://webassembly.github.io/spec/web-api/index.html), you will need `bikeshed` as describe in the section [Building the single-page HTML document](#building-the-single-page-html-document): ``` make -C web-api ``` ================================================ FILE: document/core/.gitignore ================================================ _build _static document/*.pyc ================================================ FILE: document/core/LICENSE ================================================ W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE This work is being provided by the copyright holders under the following license. LICENSE By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications: * The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. * Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice (https://www.w3.org/Consortium/Legal/copyright-software-short-notice) should be included. * Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived from [title and URI of the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)." DISCLAIMERS THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders. NOTES This version: http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document ================================================ FILE: document/core/Makefile ================================================ # Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = a4 BUILDDIR = _build STATICDIR = _static DOWNLOADDIR = _download NAME = WebAssembly # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: usage usage: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " pdf to make standalone PDF file" @echo " bikeshed to make a bikeshed wrapped single large HTML file" @echo " diff to make a diff of the bikeshed HTML file with the latest TR" @echo " WD-tar generate tar file for updating the Working Draft" @echo " WD-echidna publish the Working Draft tar file via Echidna" @echo " all to make all 3" @echo " publish to make all and push to gh-pages" @echo " help to see more options" .PHONY: help help: @echo "Usage: \`make ' where is one of" @echo " html to make standalone HTML files" @echo " pdf to make standalone PDF file" @echo " bikeshed to make a bikeshed wrapped single large HTML file" @echo " all to make all 3" @echo " publish to make all and push to gh-pages" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " epub3 to make an epub3" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" @echo " dummy to check syntax errors of document sources" .PHONY: deploy deploy: (cd ..; make dir-core deploy-core) .PHONY: publish publish: clean all deploy .PHONY: publish-main publish-main: clean main bikeshed-keep deploy .PHONY: all all: pdf html bikeshed .PHONY: main main: pdf html # Dirty hack to avoid rebuilding the Bikeshed version for every push. .PHONY: bikeshed-keep bikeshed-keep: test -e $(BUILDDIR)/html/bikeshed || \ wget -r -nH --cut-dirs=2 -P $(BUILDDIR)/html --no-check-certificate \ https://webassembly.github.io/spec/core/bikeshed || \ echo Downloaded Bikeshed. .PHONY: index index: (cd appendix; ./gen-index-instructions.py) .PHONY: pdf pdf: index latexpdf mkdir -p $(BUILDDIR)/html/$(DOWNLOADDIR) ln -f $(BUILDDIR)/latex/$(NAME).pdf $(BUILDDIR)/html/$(DOWNLOADDIR)/$(NAME).pdf .PHONY: clean clean: rm -rf $(BUILDDIR) rm -rf $(STATICDIR) .PHONY: html html: index $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html for file in `ls $(BUILDDIR)/html/*.html`; \ do \ sed s:BASEDIR:.:g <$$file >$$file.out; \ mv -f $$file.out $$file; \ done for file in `ls $(BUILDDIR)/html/*/*.html`; \ do \ sed s:BASEDIR:..:g <$$file >$$file.out; \ mv -f $$file.out $$file; \ done @echo @echo "Build finished. The HTML pages are in `pwd`/$(BUILDDIR)/html/." .PHONY: dirhtml dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." .PHONY: singlehtml singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." .PHONY: bikeshed bikeshed: $(SPHINXBUILD) -b singlehtml -c util/bikeshed \ $(ALLSPHINXOPTS) $(BUILDDIR)/bikeshed_singlehtml python util/bikeshed_fixup.py $(BUILDDIR)/bikeshed_singlehtml/index.html \ >$(BUILDDIR)/bikeshed_singlehtml/index_fixed.html mkdir -p $(BUILDDIR)/bikeshed_mathjax/ bikeshed spec index.bs $(BUILDDIR)/bikeshed_mathjax/index.html mkdir -p $(BUILDDIR)/html/bikeshed/ (cd util/katex/ && yarn && yarn build && npm install --only=prod) python util/mathjax2katex.py $(BUILDDIR)/bikeshed_mathjax/index.html \ >$(BUILDDIR)/html/bikeshed/index.html mkdir -p $(BUILDDIR)/html/bikeshed/katex/dist/ cp -r util/katex/dist/* $(BUILDDIR)/html/bikeshed/katex/dist/ patch -p0 $(BUILDDIR)/html/bikeshed/katex/dist/katex.css \ < util/katex_fix.patch cp $(BUILDDIR)/bikeshed_singlehtml/_static/pygments.css \ $(BUILDDIR)/html/bikeshed/ @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/html/bikeshed/." .PHONY: WD-tar WD-tar: bikeshed @echo "Building tar file..." tar cvf \ $(BUILDDIR)/WD.tar \ --transform='s|$(BUILDDIR)/html/bikeshed/||' \ --transform='s|index.html|Overview.html|' \ $(BUILDDIR)/html/bikeshed/index.html \ $(BUILDDIR)/html/bikeshed/pygments.css \ $(BUILDDIR)/html/bikeshed/katex/dist/katex.css \ $(BUILDDIR)/html/bikeshed/katex/dist/fonts @echo "Built $(BUILDDIR)/WD.tar." .PHONY: WD-echidna WD-echidna: WD-tar @if [ -z $(W3C_USERNAME) ] || \ [ -z $(W3C_PASSWORD) ] || \ [ -z $(DECISION_URL) ] ; then \ echo "Must provide W3C_USERNAME, W3C_PASSWORD, and DECISION_URL environment variables"; \ exit 1; \ fi curl 'https://labs.w3.org/echidna/api/request' \ --user '$(W3C_USERNAME):$(W3C_PASSWORD)' \ -F "tar=@$(BUILDDIR)/WD.tar" \ -F "decision=$(DECISION_URL)" | tee $(BUILDDIR)/WD-echidna-id.txt @echo @echo "Published working draft. Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" .PHONY: diff diff: bikeshed @echo "Downloading the old single-file html spec..." curl `grep "^TR" index.bs | cut -d' ' -f2` -o $(BUILDDIR)/html/bikeshed/old.html @echo "Done." @echo "Diffing new against old (go get a coffee)..." perl ../util/htmldiff.pl $(BUILDDIR)/html/bikeshed/old.html $(BUILDDIR)/html/bikeshed/index.html $(BUILDDIR)/html/bikeshed/diff.html @echo "Done. The diff is at $(BUILDDIR)/html/bikeshed/diff.html" .PHONY: pickle pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." .PHONY: json json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." .PHONY: htmlhelp htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." .PHONY: qthelp qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/WebAssembly.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/WebAssembly.qhc" .PHONY: applehelp applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." .PHONY: devhelp devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/WebAssembly" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/WebAssembly" @echo "# devhelp" .PHONY: epub epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." .PHONY: epub3 epub3: $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 @echo @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." .PHONY: latex latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." .PHONY: latexpdf latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex LATEXMKOPTS=" $(BUILDDIR)/latex/LOG 2>&1 || cat $(BUILDDIR)/latex/LOG @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: latexpdfja latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: text text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." .PHONY: man man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." .PHONY: texinfo texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." .PHONY: info info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." .PHONY: gettext gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." .PHONY: changes changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." .PHONY: linkcheck linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." .PHONY: doctest doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." .PHONY: coverage coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." .PHONY: xml xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." .PHONY: pseudoxml pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." .PHONY: dummy dummy: $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy @echo @echo "Build finished. Dummy builder generates no files." ================================================ FILE: document/core/README.md ================================================ # WebAssembly Core Specification This is the official WebAssembly "language" specification. It uses [Sphinx](http://www.sphinx-doc.org/). To install that: ``` pip install sphinx ``` To make HTML (result in `_build/html`): ``` make html ``` To make PDF (result in `_build/latex`, requires LaTeX): ``` make pdf ``` To make all: ``` make all ``` Finally, to make all and update webassembly.github.io/spec with it: ``` make publish ``` Please make sure to only use that once a change has approval. ================================================ FILE: document/core/appendix/algorithm.rst ================================================ .. index:: validation, algorithm, instruction, module, binary format, opcode .. _algo-valid: Validation Algorithm -------------------- The specification of WebAssembly :ref:`validation ` is purely *declarative*. It describes the constraints that must be met by a :ref:`module ` or :ref:`instruction ` sequence to be valid. This section sketches the skeleton of a sound and complete *algorithm* for effectively validating code, i.e., sequences of :ref:`instructions `. (Other aspects of validation are straightforward to implement.) In fact, the algorithm is expressed over the flat sequence of opcodes as occurring in the :ref:`binary format `, and performs only a single pass over it. Consequently, it can be integrated directly into a decoder. The algorithm is expressed in typed pseudo code whose semantics is intended to be self-explanatory. .. index:: value type, stack, label, frame, instruction Data Structures ~~~~~~~~~~~~~~~ Types are representable as an enumeration. .. code-block:: pseudo type val_type = I32 | I64 | F32 | F64 | Funcref | Externref func is_num(t : val_type | Unknown) : bool = return t = I32 || t = I64 || t = F32 || t = F64 || t = Unknown func is_ref(t : val_type | Unknown) : bool = return t = Funcref || t = Externref || t = Unknown The algorithm uses two separate stacks: the *value stack* and the *control stack*. The former tracks the :ref:`types ` of operand values on the :ref:`stack `, the latter surrounding :ref:`structured control instructions ` and their associated :ref:`blocks `. .. code-block:: pseudo type val_stack = stack(val_type | Unknown) type ctrl_stack = stack(ctrl_frame) type ctrl_frame = { opcode : opcode start_types : list(val_type) end_types : list(val_type) height : nat unreachable : bool } For each value, the value stack records its :ref:`value type `, or :code:`Unknown` when the type is not known. For each entered block, the control stack records a *control frame* with the originating opcode, the types on the top of the operand stack at the start and end of the block (used to check its result as well as branches), the height of the operand stack at the start of the block (used to check that operands do not underflow the current block), and a flag recording whether the remainder of the block is unreachable (used to handle :ref:`stack-polymorphic ` typing after branches). For the purpose of presenting the algorithm, the operand and control stacks are simply maintained as global variables: .. code-block:: pseudo var vals : val_stack var ctrls : ctrl_stack However, these variables are not manipulated directly by the main checking function, but through a set of auxiliary functions: .. code-block:: pseudo func push_val(type : val_type | Unknown) = vals.push(type) func pop_val() : val_type | Unknown = if (vals.size() = ctrls[0].height && ctrls[0].unreachable) return Unknown error_if(vals.size() = ctrls[0].height) return vals.pop() func pop_val(expect : val_type | Unknown) : val_type | Unknown = let actual = pop_val() if (actual = Unknown) return expect if (expect = Unknown) return actual error_if(actual =/= expect) return actual func push_vals(types : list(val_type)) = foreach (t in types) push_val(t) func pop_vals(types : list(val_type)) : list(val_type) = var popped := [] foreach (t in reverse(types)) popped.append(pop_val(t)) return popped Pushing an operand value simply pushes the respective type to the value stack. Popping an operand value checks that the value stack does not underflow the current block and then removes one type. But first, a special case is handled where the block contains no known values, but has been marked as unreachable. That can occur after an unconditional branch, when the stack is typed :ref:`polymorphically `. In that case, an unknown type is returned. A second function for popping an operand value takes an expected type, which the actual operand type is checked against. The types may differ in case one of them is Unknown. The function returns the actual type popped from the stack. Finally, there are accumulative functions for pushing or popping multiple operand types. .. note:: The notation :code:`stack[i]` is meant to index the stack from the top, so that, e.g., :code:`ctrls[0]` accesses the element pushed last. The control stack is likewise manipulated through auxiliary functions: .. code-block:: pseudo func push_ctrl(opcode : opcode, in : list(val_type), out : list(val_type)) =  let frame = ctrl_frame(opcode, in, out, vals.size(), false)   ctrls.push(frame) push_vals(in) func pop_ctrl() : ctrl_frame =  error_if(ctrls.is_empty())  let frame = ctrls[0]   pop_vals(frame.end_types)   error_if(vals.size() =/= frame.height) ctrls.pop()   return frame func label_types(frame : ctrl_frame) : list(val_types) = return (if frame.opcode == loop then frame.start_types else frame.end_types) func unreachable() =   vals.resize(ctrls[0].height)   ctrls[0].unreachable := true Pushing a control frame takes the types of the label and result values. It allocates a new frame record recording them along with the current height of the operand stack and marks the block as reachable. Popping a frame first checks that the control stack is not empty. It then verifies that the operand stack contains the right types of values expected at the end of the exited block and pops them off the operand stack. Afterwards, it checks that the stack has shrunk back to its initial height. The type of the :ref:`label ` associated with a control frame is either that of the stack at the start or the end of the frame, determined by the opcode that it originates from. Finally, the current frame can be marked as unreachable. In that case, all existing operand types are purged from the value stack, in order to allow for the :ref:`stack-polymorphism ` logic in :code:`pop_val` to take effect. .. note:: Even with the unreachable flag set, consecutive operands are still pushed to and popped from the operand stack. That is necessary to detect invalid :ref:`examples ` like :math:`(\UNREACHABLE~(\I32.\CONST)~\I64.\ADD)`. However, a polymorphic stack cannot underflow, but instead generates :code:`Unknown` types as needed. .. index:: opcode Validation of Opcode Sequences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following function shows the validation of a number of representative instructions that manipulate the stack. Other instructions are checked in a similar manner. .. note:: Various instructions not shown here will additionally require the presence of a validation :ref:`context ` for checking uses of :ref:`indices `. That is an easy addition and therefore omitted from this presentation. .. code-block:: pseudo func validate(opcode) = switch (opcode) case (i32.add) pop_val(I32) pop_val(I32) push_val(I32) case (drop) pop_val() case (select) pop_val(I32) let t1 = pop_val() let t2 = pop_val() error_if(not (is_num(t1) && is_num(t2))) error_if(t1 =/= t2 && t1 =/= Unknown && t2 =/= Unknown) push_val(if (t1 = Unknown) t2 else t1) case (select t) pop_val(I32) pop_val(t) pop_val(t) push_val(t)    case (unreachable)       unreachable() case (block t1*->t2*) pop_vals([t1*]) push_ctrl(block, [t1*], [t2*]) case (loop t1*->t2*) pop_vals([t1*]) push_ctrl(loop, [t1*], [t2*]) case (if t1*->t2*) pop_val(I32) pop_vals([t1*]) push_ctrl(if, [t1*], [t2*]) case (end) let frame = pop_ctrl() push_vals(frame.end_types) case (else) let frame = pop_ctrl() error_if(frame.opcode =/= if) push_ctrl(else, frame.start_types, frame.end_types) case (br n)      error_if(ctrls.size() < n)       pop_vals(label_types(ctrls[n]))       unreachable() case (br_if n)      error_if(ctrls.size() < n) pop_val(I32)       pop_vals(label_types(ctrls[n]))       push_vals(label_types(ctrls[n]))    case (br_table n* m) pop_val(I32)       error_if(ctrls.size() < m) let arity = label_types(ctrls[m]).size()       foreach (n in n*)         error_if(ctrls.size() < n)         error_if(label_types(ctrls[n]).size() =/= arity) push_vals(pop_vals(label_types(ctrls[n]))) pop_vals(label_types(ctrls[m]))       unreachable() .. note:: It is an invariant under the current WebAssembly instruction set that an operand of :code:`Unknown` type is never duplicated on the stack. This would change if the language were extended with stack instructions like :code:`dup`. Under such an extension, the above algorithm would need to be refined by replacing the :code:`Unknown` type with proper *type variables* to ensure that all uses are consistent. ================================================ FILE: document/core/appendix/custom.rst ================================================ .. index:: custom section, section, binary format Custom Sections --------------- This appendix defines dedicated :ref:`custom sections ` for WebAssembly's :ref:`binary format `. Such sections do not contribute to, or otherwise affect, the WebAssembly semantics, and like any custom section they may be ignored by an implementation. However, they provide useful meta data that implementations can make use of to improve user experience or take compilation hints. Currently, only one dedicated custom section is defined, the :ref:`name section`. .. index:: ! name section, name, Unicode UTF-8 .. _binary-namesec: Name Section ~~~~~~~~~~~~ The *name section* is a :ref:`custom section ` whose name string is itself :math:`\text{name}`. The name section should appear only once in a module, and only after the :ref:`data section `. The purpose of this section is to attach printable names to definitions in a module, which e.g. can be used by a debugger or when parts of the module are to be rendered in :ref:`text form `. .. note:: All :ref:`names ` are represented in |Unicode|_ encoded in UTF-8. Names need not be unique. .. _binary-namesubsection: Subsections ........... The :ref:`data ` of a name section consists of a sequence of *subsections*. Each subsection consists of a * a one-byte subsection *id*, * the |U32| *size* of the contents, in bytes, * the actual *contents*, whose structure is depended on the subsection id. .. math:: \begin{array}{llcll} \production{name section} & \Bnamesec &::=& \Bsection_0(\Bnamedata) \\ \production{name data} & \Bnamedata &::=& n{:}\Bname & (\iff n = \text{name}) \\ &&& \Bmodulenamesubsec^? \\ &&& \Bfuncnamesubsec^? \\ &&& \Blocalnamesubsec^? \\ \production{name subsection} & \Bnamesubsection_N(\B{B}) &::=& N{:}\Bbyte~~\X{size}{:}\Bu32~~\B{B} & (\iff \X{size} = ||\B{B}||) \\ \end{array} The following subsection ids are used: == =========================================== Id Subsection == =========================================== 0 :ref:`module name ` 1 :ref:`function names ` 2 :ref:`local names ` == =========================================== Each subsection may occur at most once, and in order of increasing id. .. index:: ! name map, index, index space .. _binary-indirectnamemap: .. _binary-namemap: Name Maps ......... A *name map* assigns :ref:`names ` to :ref:`indices ` in a given :ref:`index space `. It consists of a :ref:`vector ` of index/name pairs in order of increasing index value. Each index must be unique, but the assigned names need not be. .. math:: \begin{array}{llclll} \production{name map} & \Bnamemap &::=& \Bvec(\Bnameassoc) \\ \production{name association} & \Bnameassoc &::=& \Bidx~\Bname \\ \end{array} An *indirect name map* assigns :ref:`names ` to a two-dimensional :ref:`index space `, where secondary indices are *grouped* by primary indices. It consists of a vector of primary index/name map pairs in order of increasing index value, where each name map in turn maps secondary indices to names. Each primary index must be unique, and likewise each secondary index per individual name map. .. math:: \begin{array}{llclll} \production{indirect name map} & \Bindirectnamemap &::=& \Bvec(\Bindirectnameassoc) \\ \production{indirect name association} & \Bindirectnameassoc &::=& \Bidx~\Bnamemap \\ \end{array} .. index:: module .. _binary-modulenamesec: Module Names ............ The *module name subsection* has the id 0. It simply consists of a single :ref:`name ` that is assigned to the module itself. .. math:: \begin{array}{llclll} \production{module name subsection} & \Bmodulenamesubsec &::=& \Bnamesubsection_0(\Bname) \\ \end{array} .. index:: function, function index .. _binary-funcnamesec: Function Names .............. The *function name subsection* has the id 1. It consists of a :ref:`name map ` assigning function names to :ref:`function indices `. .. math:: \begin{array}{llclll} \production{function name subsection} & \Bfuncnamesubsec &::=& \Bnamesubsection_1(\Bnamemap) \\ \end{array} .. index:: function, local, function index, local index .. _binary-localnamesec: Local Names ........... The *local name subsection* has the id 2. It consists of an :ref:`indirect name map ` assigning local names to :ref:`local indices ` grouped by :ref:`function indices `. .. math:: \begin{array}{llclll} \production{local name subsection} & \Blocalnamesubsec &::=& \Bnamesubsection_2(\Bindirectnamemap) \\ \end{array} ================================================ FILE: document/core/appendix/embedding.rst ================================================ .. index:: ! embedding, embedder, implementation, host .. _embed: Embedding --------- A WebAssembly implementation will typically be *embedded* into a *host* environment. An *embedder* implements the connection between such a host environment and the WebAssembly semantics as defined in the main body of this specification. An embedder is expected to interact with the semantics in well-defined ways. This section defines a suitable interface to the WebAssembly semantics in the form of entry points through which an embedder can access it. The interface is intended to be complete, in the sense that an embedder does not need to reference other functional parts of the WebAssembly specification directly. .. note:: On the other hand, an embedder does not need to provide the host environment with access to all functionality defined in this interface. For example, an implementation may not support :ref:`parsing ` of the :ref:`text format `. Types ~~~~~ In the description of the embedder interface, syntactic classes from the :ref:`abstract syntax ` and the :ref:`runtime's abstract machine ` are used as names for variables that range over the possible objects from that class. Hence, these syntactic classes can also be interpreted as types. For numeric parameters, notation like :math:`n:\u32` is used to specify a symbolic name in addition to the respective value range. .. _embed-error: Errors ~~~~~~ Failure of an interface operation is indicated by an auxiliary syntactic class: .. math:: \begin{array}{llll} \production{(error)} & \error &::=& \ERROR \\ \end{array} In addition to the error conditions specified explicitly in this section, implementations may also return errors when specific :ref:`implementation limitations ` are reached. .. note:: Errors are abstract and unspecific with this definition. Implementations can refine it to carry suitable classifications and diagnostic messages. Pre- and Post-Conditions ~~~~~~~~~~~~~~~~~~~~~~~~ Some operations state *pre-conditions* about their arguments or *post-conditions* about their results. It is the embedder's responsibility to meet the pre-conditions. If it does, the post conditions are guaranteed by the semantics. In addition to pre- and post-conditions explicitly stated with each operation, the specification adopts the following conventions for :ref:`runtime objects ` (:math:`store`, :math:`\moduleinst`, :math:`\externval`, :ref:`addresses `): * Every runtime object passed as a parameter must be :ref:`valid ` per an implicit pre-condition. * Every runtime object returned as a result is :ref:`valid ` per an implicit post-condition. .. note:: As long as an embedder treats runtime objects as abstract and only creates and manipulates them through the interface defined here, all implicit pre-conditions are automatically met. .. index:: allocation, store .. _embed-store: Store ~~~~~ .. _embed-store-init: :math:`\F{store\_init}() : \store` .................................. 1. Return the empty :ref:`store `. .. math:: \begin{array}{lclll} \F{store\_init}() &=& \{ \SFUNCS~\epsilon,~ \SMEMS~\epsilon,~ \STABLES~\epsilon,~ \SGLOBALS~\epsilon \} \\ \end{array} .. index:: module .. _embed-module: Modules ~~~~~~~ .. index:: binary format .. _embed-module-decode: :math:`\F{module\_decode}(\byte^\ast) : \module ~|~ \error` ........................................................... 1. If there exists a derivation for the :ref:`byte ` sequence :math:`\byte^\ast` as a :math:`\Bmodule` according to the :ref:`binary grammar for modules `, yielding a :ref:`module ` :math:`m`, then return :math:`m`. 2. Else, return :math:`\ERROR`. .. math:: \begin{array}{lclll} \F{module\_decode}(b^\ast) &=& m && (\iff \Bmodule \stackrel\ast\Longrightarrow m{:}b^\ast) \\ \F{module\_decode}(b^\ast) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: text format .. _embed-module-parse: :math:`\F{module\_parse}(\char^\ast) : \module ~|~ \error` .......................................................... 1. If there exists a derivation for the :ref:`source ` :math:`\char^\ast` as a :math:`\Tmodule` according to the :ref:`text grammar for modules `, yielding a :ref:`module ` :math:`m`, then return :math:`m`. 2. Else, return :math:`\ERROR`. .. math:: \begin{array}{lclll} \F{module\_parse}(c^\ast) &=& m && (\iff \Tmodule \stackrel\ast\Longrightarrow m{:}c^\ast) \\ \F{module\_parse}(c^\ast) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: validation .. _embed-module-validate: :math:`\F{module\_validate}(\module) : \error^?` ................................................ 1. If :math:`\module` is :ref:`valid `, then return nothing. 2. Else, return :math:`\ERROR`. .. math:: \begin{array}{lclll} \F{module\_validate}(m) &=& \epsilon && (\iff {} \vdashmodule m : \externtype^\ast \to {\externtype'}^\ast) \\ \F{module\_validate}(m) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: instantiation, module instance .. _embed-module-instantiate: :math:`\F{module\_instantiate}(\store, \module, \externval^\ast) : (\store, \moduleinst ~|~ \error)` .................................................................................................... 1. Try :ref:`instantiating ` :math:`\module` in :math:`\store` with :ref:`external values ` :math:`\externval^\ast` as imports: a. If it succeeds with a :ref:`module instance ` :math:`\moduleinst`, then let :math:`\X{result}` be :math:`\moduleinst`. b. Else, let :math:`\X{result}` be :math:`\ERROR`. 2. Return the new store paired with :math:`\X{result}`. .. math:: \begin{array}{lclll} \F{module\_instantiate}(S, m, \X{ev}^\ast) &=& (S', F.\AMODULE) && (\iff \instantiate(S, m, \X{ev}^\ast) \stepto^\ast S'; F; \epsilon) \\ \F{module\_instantiate}(S, m, \X{ev}^\ast) &=& (S', \ERROR) && (\iff \instantiate(S, m, \X{ev}^\ast) \stepto^\ast S'; F; \TRAP) \\ \end{array} .. note:: The store may be modified even in case of an error. .. index:: import .. _embed-module-imports: :math:`\F{module\_imports}(\module) : (\name, \name, \externtype)^\ast` ....................................................................... 1. Pre-condition: :math:`\module` is :ref:`valid ` with external import types :math:`\externtype^\ast` and external export types :math:`{\externtype'}^\ast`. 2. Let :math:`\import^\ast` be the :ref:`imports ` :math:`\module.\MIMPORTS`. 3. Assert: the length of :math:`\import^\ast` equals the length of :math:`\externtype^\ast`. 4. For each :math:`\import_i` in :math:`\import^\ast` and corresponding :math:`\externtype_i` in :math:`\externtype^\ast`, do: a. Let :math:`\X{result}_i` be the triple :math:`(\import_i.\IMODULE, \import_i.\INAME, \externtype_i)`. 5. Return the concatenation of all :math:`\X{result}_i`, in index order. 6. Post-condition: each :math:`\externtype_i` is :ref:`valid `. .. math:: ~ \\ \begin{array}{lclll} \F{module\_imports}(m) &=& (\X{im}.\IMODULE, \X{im}.\INAME, \externtype)^\ast \\ && \qquad (\iff \X{im}^\ast = m.\MIMPORTS \wedge {} \vdashmodule m : \externtype^\ast \to {\externtype'}^\ast) \\ \end{array} .. index:: export .. _embed-module-exports: :math:`\F{module\_exports}(\module) : (\name, \externtype)^\ast` ................................................................ 1. Pre-condition: :math:`\module` is :ref:`valid ` with external import types :math:`\externtype^\ast` and external export types :math:`{\externtype'}^\ast`. 2. Let :math:`\export^\ast` be the :ref:`exports ` :math:`\module.\MEXPORTS`. 3. Assert: the length of :math:`\export^\ast` equals the length of :math:`{\externtype'}^\ast`. 4. For each :math:`\export_i` in :math:`\export^\ast` and corresponding :math:`\externtype'_i` in :math:`{\externtype'}^\ast`, do: a. Let :math:`\X{result}_i` be the pair :math:`(\export_i.\ENAME, \externtype'_i)`. 5. Return the concatenation of all :math:`\X{result}_i`, in index order. 6. Post-condition: each :math:`\externtype'_i` is :ref:`valid `. .. math:: ~ \\ \begin{array}{lclll} \F{module\_exports}(m) &=& (\X{ex}.\ENAME, \externtype')^\ast \\ && \qquad (\iff \X{ex}^\ast = m.\MEXPORTS \wedge {} \vdashmodule m : \externtype^\ast \to {\externtype'}^\ast) \\ \end{array} .. index:: module, module instance .. _embed-instance: Module Instances ~~~~~~~~~~~~~~~~ .. index:: export, export instance .. _embed-instance-export: :math:`\F{instance\_export}(\moduleinst, \name) : \externval ~|~ \error` ........................................................................ 1. Assert: due to :ref:`validity ` of the :ref:`module instance ` :math:`\moduleinst`, all its :ref:`export names ` are different. 2. If there exists an :math:`\exportinst_i` in :math:`\moduleinst.\MIEXPORTS` such that :ref:`name ` :math:`\exportinst_i.\EINAME` equals :math:`\name`, then: a. Return the :ref:`external value ` :math:`\exportinst_i.\EIVALUE`. 3. Else, return :math:`\ERROR`. .. math:: ~ \\ \begin{array}{lclll} \F{instance\_export}(m, \name) &=& m.\MIEXPORTS[i].\EIVALUE && (\iff m.\MEXPORTS[i].\EINAME = \name) \\ \F{instance\_export}(m, \name) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: function, host function, function address, function instance, function type, store .. _embed-func: Functions ~~~~~~~~~ .. _embed-func-alloc: :math:`\F{func\_alloc}(\store, \functype, \hostfunc) : (\store, \funcaddr)` ........................................................................... 1. Pre-condition: :math:`\functype` is :math:`valid `. 2. Let :math:`\funcaddr` be the result of :ref:`allocating a host function ` in :math:`\store` with :ref:`function type ` :math:`\functype` and host function code :math:`\hostfunc`. 3. Return the new store paired with :math:`\funcaddr`. .. math:: \begin{array}{lclll} \F{func\_alloc}(S, \X{ft}, \X{code}) &=& (S', \X{a}) && (\iff \allochostfunc(S, \X{ft}, \X{code}) = S', \X{a}) \\ \end{array} .. note:: This operation assumes that :math:`\hostfunc` satisfies the :ref:`pre- and post-conditions ` required for a function instance with type :math:`\functype`. Regular (non-host) function instances can only be created indirectly through :ref:`module instantiation `. .. _embed-func-type: :math:`\F{func\_type}(\store, \funcaddr) : \functype` ..................................................... 1. Return :math:`S.\SFUNCS[a].\FITYPE`. 2. Post-condition: the returned :ref:`function type ` is :ref:`valid `. .. math:: \begin{array}{lclll} \F{func\_type}(S, a) &=& S.\SFUNCS[a].\FITYPE \\ \end{array} .. index:: invocation, value, result .. _embed-func-invoke: :math:`\F{func\_invoke}(\store, \funcaddr, \val^\ast) : (\store, \val^\ast ~|~ \error)` ........................................................................................ 1. Try :ref:`invoking ` the function :math:`\funcaddr` in :math:`\store` with :ref:`values ` :math:`\val^\ast` as arguments: a. If it succeeds with :ref:`values ` :math:`{\val'}^\ast` as results, then let :math:`\X{result}` be :math:`{\val'}^\ast`. b. Else it has trapped, hence let :math:`\X{result}` be :math:`\ERROR`. 2. Return the new store paired with :math:`\X{result}`. .. math:: ~ \\ \begin{array}{lclll} \F{func\_invoke}(S, a, v^\ast) &=& (S', {v'}^\ast) && (\iff \invoke(S, a, v^\ast) \stepto^\ast S'; F; {v'}^\ast) \\ \F{func\_invoke}(S, a, v^\ast) &=& (S', \ERROR) && (\iff \invoke(S, a, v^\ast) \stepto^\ast S'; F; \TRAP) \\ \end{array} .. note:: The store may be modified even in case of an error. .. index:: table, table address, store, table instance, table type, element, function address .. _embed-table: Tables ~~~~~~ .. _embed-table-alloc: :math:`\F{table\_alloc}(\store, \tabletype) : (\store, \tableaddr, \reff)` .......................................................................... 1. Pre-condition: :math:`\tabletype` is :math:`valid `. 2. Let :math:`\tableaddr` be the result of :ref:`allocating a table ` in :math:`\store` with :ref:`table type ` :math:`\tabletype` and initialization value :math:`\reff`. 3. Return the new store paired with :math:`\tableaddr`. .. math:: \begin{array}{lclll} \F{table\_alloc}(S, \X{tt}, r) &=& (S', \X{a}) && (\iff \alloctable(S, \X{tt}, r) = S', \X{a}) \\ \end{array} .. _embed-table-type: :math:`\F{table\_type}(\store, \tableaddr) : \tabletype` ........................................................ 1. Return :math:`S.\STABLES[a].\TITYPE`. 2. Post-condition: the returned :ref:`table type ` is :math:`valid `. .. math:: \begin{array}{lclll} \F{table\_type}(S, a) &=& S.\STABLES[a].\TITYPE \\ \end{array} .. _embed-table-read: :math:`\F{table\_read}(\store, \tableaddr, i:\u32) : \reff ~|~ \error` ...................................................................... 1. Let :math:`\X{ti}` be the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]`. 2. If :math:`i` is larger than or equal to the length of :math:`\X{ti}.\TIELEM`, then return :math:`\ERROR`. 3. Else, return the :ref:`reference value ` :math:`\X{ti}.\TIELEM[i]`. .. math:: \begin{array}{lclll} \F{table\_read}(S, a, i) &=& r && (\iff S.\STABLES[a].\TIELEM[i] = r) \\ \F{table\_read}(S, a, i) &=& \ERROR && (\otherwise) \\ \end{array} .. _embed-table-write: :math:`\F{table\_write}(\store, \tableaddr, i:\u32, \reff) : \store ~|~ \error` ............................................................................... 1. Let :math:`\X{ti}` be the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]`. 2. If :math:`i` is larger than or equal to the length of :math:`\X{ti}.\TIELEM`, then return :math:`\ERROR`. 3. Replace :math:`\X{ti}.\TIELEM[i]` with the :ref:`reference value ` :math:`\reff`. 4. Return the updated store. .. math:: \begin{array}{lclll} \F{table\_write}(S, a, i, r) &=& S' && (\iff S' = S \with \STABLES[a].\TIELEM[i] = r) \\ \F{table\_write}(S, a, i, r) &=& \ERROR && (\otherwise) \\ \end{array} .. _embed-table-size: :math:`\F{table\_size}(\store, \tableaddr) : \u32` .................................................. 1. Return the length of :math:`\store.\STABLES[\tableaddr].\TIELEM`. .. math:: ~ \\ \begin{array}{lclll} \F{table\_size}(S, a) &=& n && (\iff |S.\STABLES[a].\TIELEM| = n) \\ \end{array} .. _embed-table-grow: :math:`\F{table\_grow}(\store, \tableaddr, n:\u32, \reff) : \store ~|~ \error` .............................................................................. 1. Try :ref:`growing ` the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]` by :math:`n` elements with initialization value :math:`\reff`: a. If it succeeds, return the updated store. b. Else, return :math:`\ERROR`. .. math:: ~ \\ \begin{array}{lclll} \F{table\_grow}(S, a, n, r) &=& S' && (\iff S' = S \with \STABLES[a] = \growtable(S.\STABLES[a], n, r)) \\ \F{table\_grow}(S, a, n, r) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: memory, memory address, store, memory instance, memory type, byte .. _embed-mem: Memories ~~~~~~~~ .. _embed-mem-alloc: :math:`\F{mem\_alloc}(\store, \memtype) : (\store, \memaddr)` ................................................................ 1. Pre-condition: :math:`\memtype` is :math:`valid `. 2. Let :math:`\memaddr` be the result of :ref:`allocating a memory ` in :math:`\store` with :ref:`memory type ` :math:`\memtype`. 3. Return the new store paired with :math:`\memaddr`. .. math:: \begin{array}{lclll} \F{mem\_alloc}(S, \X{mt}) &=& (S', \X{a}) && (\iff \allocmem(S, \X{mt}) = S', \X{a}) \\ \end{array} .. _embed-mem-type: :math:`\F{mem\_type}(\store, \memaddr) : \memtype` .................................................. 1. Return :math:`S.\SMEMS[a].\MITYPE`. 2. Post-condition: the returned :ref:`memory type ` is :math:`valid `. .. math:: \begin{array}{lclll} \F{mem\_type}(S, a) &=& S.\SMEMS[a].\MITYPE \\ \end{array} .. _embed-mem-read: :math:`\F{mem\_read}(\store, \memaddr, i:\u32) : \byte ~|~ \error` .................................................................. 1. Let :math:`\X{mi}` be the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]`. 2. If :math:`i` is larger than or equal to the length of :math:`\X{mi}.\MIDATA`, then return :math:`\ERROR`. 3. Else, return the :ref:`byte ` :math:`\X{mi}.\MIDATA[i]`. .. math:: \begin{array}{lclll} \F{mem\_read}(S, a, i) &=& b && (\iff S.\SMEMS[a].\MIDATA[i] = b) \\ \F{mem\_read}(S, a, i) &=& \ERROR && (\otherwise) \\ \end{array} .. _embed-mem-write: :math:`\F{mem\_write}(\store, \memaddr, i:\u32, \byte) : \store ~|~ \error` ........................................................................... 1. Let :math:`\X{mi}` be the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]`. 2. If :math:`\u32` is larger than or equal to the length of :math:`\X{mi}.\MIDATA`, then return :math:`\ERROR`. 3. Replace :math:`\X{mi}.\MIDATA[i]` with :math:`\byte`. 4. Return the updated store. .. math:: \begin{array}{lclll} \F{mem\_write}(S, a, i, b) &=& S' && (\iff S' = S \with \SMEMS[a].\MIDATA[i] = b) \\ \F{mem\_write}(S, a, i, b) &=& \ERROR && (\otherwise) \\ \end{array} .. _embed-mem-size: :math:`\F{mem\_size}(\store, \memaddr) : \u32` .............................................. 1. Return the length of :math:`\store.\SMEMS[\memaddr].\MIDATA` divided by the :ref:`page size `. .. math:: ~ \\ \begin{array}{lclll} \F{mem\_size}(S, a) &=& n && (\iff |S.\SMEMS[a].\MIDATA| = n \cdot 64\,\F{Ki}) \\ \end{array} .. _embed-mem-grow: :math:`\F{mem\_grow}(\store, \memaddr, n:\u32) : \store ~|~ \error` ................................................................... 1. Try :ref:`growing ` the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]` by :math:`n` :ref:`pages `: a. If it succeeds, return the updated store. b. Else, return :math:`\ERROR`. .. math:: ~ \\ \begin{array}{lclll} \F{mem\_grow}(S, a, n) &=& S' && (\iff S' = S \with \SMEMS[a] = \growmem(S.\SMEMS[a], n)) \\ \F{mem\_grow}(S, a, n) &=& \ERROR && (\otherwise) \\ \end{array} .. index:: global, global address, store, global instance, global type, value .. _embed-global: Globals ~~~~~~~ .. _embed-global-alloc: :math:`\F{global\_alloc}(\store, \globaltype, \val) : (\store, \globaladdr)` ............................................................................ 1. Pre-condition: :math:`\globaltype` is :math:`valid `. 2. Let :math:`\globaladdr` be the result of :ref:`allocating a global ` in :math:`\store` with :ref:`global type ` :math:`\globaltype` and initialization value :math:`\val`. 3. Return the new store paired with :math:`\globaladdr`. .. math:: \begin{array}{lclll} \F{global\_alloc}(S, \X{gt}, v) &=& (S', \X{a}) && (\iff \allocglobal(S, \X{gt}, v) = S', \X{a}) \\ \end{array} .. _embed-global-type: :math:`\F{global\_type}(\store, \globaladdr) : \globaltype` ........................................................... 1. Return :math:`S.\SGLOBALS[a].\GITYPE`. 2. Post-condition: the returned :ref:`global type ` is :math:`valid `. .. math:: \begin{array}{lclll} \F{global\_type}(S, a) &=& S.\SGLOBALS[a].\GITYPE \\ \end{array} .. _embed-global-read: :math:`\F{global\_read}(\store, \globaladdr) : \val` .................................................... 1. Let :math:`\X{gi}` be the :ref:`global instance ` :math:`\store.\SGLOBALS[\globaladdr]`. 2. Return the :ref:`value ` :math:`\X{gi}.\GIVALUE`. .. math:: \begin{array}{lclll} \F{global\_read}(S, a) &=& v && (\iff S.\SGLOBALS[a].\GIVALUE = v) \\ \end{array} .. _embed-global-write: :math:`\F{global\_write}(\store, \globaladdr, \val) : \store ~|~ \error` ........................................................................ 1. Let :math:`\X{gi}` be the :ref:`global instance ` :math:`\store.\SGLOBALS[\globaladdr]`. 2. Let :math:`\mut~t` be the structure of the :ref:`global type ` :math:`\X{gi}.\GITYPE`. 3. If :math:`\mut` is not :math:`\MVAR`, then return :math:`\ERROR`. 4. Replace :math:`\X{gi}.\GIVALUE` with the :ref:`value ` :math:`\val`. 5. Return the updated store. .. math:: ~ \\ \begin{array}{lclll} \F{global\_write}(S, a, v) &=& S' && (\iff S.\SGLOBALS[a].\GITYPE = \MVAR~t \wedge S' = S \with \SGLOBALS[a].\GIVALUE = v) \\ \F{global\_write}(S, a, v) &=& \ERROR && (\otherwise) \\ \end{array} ================================================ FILE: document/core/appendix/gen-index-instructions.py ================================================ #!/usr/bin/env python3 # This script generates the `index-instructions.rst` file. The table in that # file is particularly annoying to update by hand, since the Restructured Text # format requires the header and columns to line up properly. This is # especially tedious when merging changes from the upstream spec, or merging a # proposal back to the spec when it is standardized. import os SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) INDEX_INSTRUCTIONS_RST = os.path.join(SCRIPT_DIR, 'index-instructions.rst') HEADER = """\ .. DO NOT EDIT: This file is auto-generated by the gen-index-instructions.py script. .. index:: instruction .. _index-instr: Index of Instructions --------------------- """ COLUMNS = [ 'Instruction', 'Binary Opcode', 'Type', 'Validation', 'Execution', ] def MathWrap(s, default=''): if s is None: return default else: return f':math:`{s}`' def RefWrap(s, kind): if s is None: return '' else: return f':ref:`{kind} <{s}>`' def Instruction(name, opcode, type=None, validation=None, execution=None, operator=None): if operator: execution_str = ', '.join([RefWrap(execution, 'execution'), RefWrap(operator, 'operator')]) else: execution_str = RefWrap(execution, 'execution') return ( MathWrap(name, '(reserved)'), MathWrap(opcode), MathWrap(type), RefWrap(validation, 'validation'), execution_str ) INSTRUCTIONS = [ Instruction(r'\UNREACHABLE', r'\hex{00}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-unreachable', r'exec-unreachable'), Instruction(r'\NOP', r'\hex{01}', r'[] \to []', r'valid-nop', r'exec-nop'), Instruction(r'\BLOCK~\X{bt}', r'\hex{02}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-block', r'exec-block'), Instruction(r'\LOOP~\X{bt}', r'\hex{03}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-loop', r'exec-loop'), Instruction(r'\IF~\X{bt}', r'\hex{04}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-if', r'exec-if'), Instruction(r'\ELSE', r'\hex{05}'), Instruction(None, r'\hex{06}'), Instruction(None, r'\hex{07}'), Instruction(None, r'\hex{08}'), Instruction(None, r'\hex{09}'), Instruction(None, r'\hex{0A}'), Instruction(r'\END', r'\hex{0B}'), Instruction(r'\BR~l', r'\hex{0C}', r'[t_1^\ast~t^\ast] \to [t_2^\ast]', r'valid-br', r'exec-br'), Instruction(r'\BRIF~l', r'\hex{0D}', r'[t^\ast~\I32] \to [t^\ast]', r'valid-br_if', r'exec-br_if'), Instruction(r'\BRTABLE~l^\ast~l', r'\hex{0E}', r'[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]', r'valid-br_table', r'exec-br_table'), Instruction(r'\RETURN', r'\hex{0F}', r'[t_1^\ast~t^\ast] \to [t_2^\ast]', r'valid-return', r'exec-return'), Instruction(r'\CALL~x', r'\hex{10}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-call', r'exec-call'), Instruction(r'\CALLINDIRECT~x~y', r'\hex{11}', r'[t_1^\ast~\I32] \to [t_2^\ast]', r'valid-call_indirect', r'exec-call_indirect'), Instruction(None, r'\hex{12}'), Instruction(None, r'\hex{13}'), Instruction(None, r'\hex{14}'), Instruction(None, r'\hex{15}'), Instruction(None, r'\hex{16}'), Instruction(None, r'\hex{17}'), Instruction(None, r'\hex{18}'), Instruction(None, r'\hex{19}'), Instruction(r'\DROP', r'\hex{1A}', r'[t] \to []', r'valid-drop', r'exec-drop'), Instruction(r'\SELECT', r'\hex{1B}', r'[t~t~\I32] \to [t]', r'valid-select', r'exec-select'), Instruction(r'\SELECT~t', r'\hex{1C}', r'[t~t~\I32] \to [t]', r'valid-select', r'exec-select'), Instruction(None, r'\hex{1D}'), Instruction(None, r'\hex{1E}'), Instruction(None, r'\hex{1F}'), Instruction(r'\LOCALGET~x', r'\hex{20}', r'[] \to [t]', r'valid-local.get', r'exec-local.get'), Instruction(r'\LOCALSET~x', r'\hex{21}', r'[t] \to []', r'valid-local.set', r'exec-local.set'), Instruction(r'\LOCALTEE~x', r'\hex{22}', r'[t] \to [t]', r'valid-local.tee', r'exec-local.tee'), Instruction(r'\GLOBALGET~x', r'\hex{23}', r'[] \to [t]', r'valid-global.get', r'exec-global.get'), Instruction(r'\GLOBALSET~x', r'\hex{24}', r'[t] \to []', r'valid-global.set', r'exec-global.set'), Instruction(r'\TABLEGET~x', r'\hex{25}', r'[\I32] \to [t]', r'valid-table.get', r'exec-table.get'), Instruction(r'\TABLESET~x', r'\hex{26}', r'[\I32~t] \to []', r'valid-table.set', r'exec-table.set'), Instruction(None, r'\hex{27}'), Instruction(r'\I32.\LOAD~\memarg', r'\hex{28}', r'[\I32] \to [\I32]', r'valid-load', r'exec-load'), Instruction(r'\I64.\LOAD~\memarg', r'\hex{29}', r'[\I32] \to [\I64]', r'valid-load', r'exec-load'), Instruction(r'\F32.\LOAD~\memarg', r'\hex{2A}', r'[\I32] \to [\F32]', r'valid-load', r'exec-load'), Instruction(r'\F64.\LOAD~\memarg', r'\hex{2B}', r'[\I32] \to [\F64]', r'valid-load', r'exec-load'), Instruction(r'\I32.\LOAD\K{8\_s}~\memarg', r'\hex{2C}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I32.\LOAD\K{8\_u}~\memarg', r'\hex{2D}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I32.\LOAD\K{16\_s}~\memarg', r'\hex{2E}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I32.\LOAD\K{16\_u}~\memarg', r'\hex{2F}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{8\_s}~\memarg', r'\hex{30}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{8\_u}~\memarg', r'\hex{31}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{16\_s}~\memarg', r'\hex{32}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{16\_u}~\memarg', r'\hex{33}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{32\_s}~\memarg', r'\hex{34}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I64.\LOAD\K{32\_u}~\memarg', r'\hex{35}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), Instruction(r'\I32.\STORE~\memarg', r'\hex{36}', r'[\I32~\I32] \to []', r'valid-store', r'exec-store'), Instruction(r'\I64.\STORE~\memarg', r'\hex{37}', r'[\I32~\I64] \to []', r'valid-store', r'exec-store'), Instruction(r'\F32.\STORE~\memarg', r'\hex{38}', r'[\I32~\F32] \to []', r'valid-store', r'exec-store'), Instruction(r'\F64.\STORE~\memarg', r'\hex{39}', r'[\I32~\F64] \to []', r'valid-store', r'exec-store'), Instruction(r'\I32.\STORE\K{8}~\memarg', r'\hex{3A}', r'[\I32~\I32] \to []', r'valid-storen', r'exec-storen'), Instruction(r'\I32.\STORE\K{16}~\memarg', r'\hex{3B}', r'[\I32~\I32] \to []', r'valid-storen', r'exec-storen'), Instruction(r'\I64.\STORE\K{8}~\memarg', r'\hex{3C}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), Instruction(r'\I64.\STORE\K{16}~\memarg', r'\hex{3D}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), Instruction(r'\I64.\STORE\K{32}~\memarg', r'\hex{3E}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), Instruction(r'\MEMORYSIZE', r'\hex{3F}', r'[] \to [\I32]', r'valid-memory.size', r'exec-memory.size'), Instruction(r'\MEMORYGROW', r'\hex{40}', r'[\I32] \to [\I32]', r'valid-memory.grow', r'exec-memory.grow'), Instruction(r'\I32.\CONST~\i32', r'\hex{41}', r'[] \to [\I32]', r'valid-const', r'exec-const'), Instruction(r'\I64.\CONST~\i64', r'\hex{42}', r'[] \to [\I64]', r'valid-const', r'exec-const'), Instruction(r'\F32.\CONST~\f32', r'\hex{43}', r'[] \to [\F32]', r'valid-const', r'exec-const'), Instruction(r'\F64.\CONST~\f64', r'\hex{44}', r'[] \to [\F64]', r'valid-const', r'exec-const'), Instruction(r'\I32.\EQZ', r'\hex{45}', r'[\I32] \to [\I32]', r'valid-testop', r'exec-testop', r'op-ieqz'), Instruction(r'\I32.\EQ', r'\hex{46}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ieq'), Instruction(r'\I32.\NE', r'\hex{47}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ine'), Instruction(r'\I32.\LT\K{\_s}', r'\hex{48}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_s'), Instruction(r'\I32.\LT\K{\_u}', r'\hex{49}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_u'), Instruction(r'\I32.\GT\K{\_s}', r'\hex{4A}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_s'), Instruction(r'\I32.\GT\K{\_u}', r'\hex{4B}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_u'), Instruction(r'\I32.\LE\K{\_s}', r'\hex{4C}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_s'), Instruction(r'\I32.\LE\K{\_u}', r'\hex{4D}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_u'), Instruction(r'\I32.\GE\K{\_s}', r'\hex{4E}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_s'), Instruction(r'\I32.\GE\K{\_u}', r'\hex{4F}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_u'), Instruction(r'\I64.\EQZ', r'\hex{50}', r'[\I64] \to [\I32]', r'valid-testop', r'exec-testop', r'op-ieqz'), Instruction(r'\I64.\EQ', r'\hex{51}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ieq'), Instruction(r'\I64.\NE', r'\hex{52}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ine'), Instruction(r'\I64.\LT\K{\_s}', r'\hex{53}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_s'), Instruction(r'\I64.\LT\K{\_u}', r'\hex{54}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_u'), Instruction(r'\I64.\GT\K{\_s}', r'\hex{55}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_s'), Instruction(r'\I64.\GT\K{\_u}', r'\hex{56}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_u'), Instruction(r'\I64.\LE\K{\_s}', r'\hex{57}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_s'), Instruction(r'\I64.\LE\K{\_u}', r'\hex{58}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_u'), Instruction(r'\I64.\GE\K{\_s}', r'\hex{59}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_s'), Instruction(r'\I64.\GE\K{\_u}', r'\hex{5A}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_u'), Instruction(r'\F32.\EQ', r'\hex{5B}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-feq'), Instruction(r'\F32.\NE', r'\hex{5C}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fne'), Instruction(r'\F32.\LT', r'\hex{5D}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-flt'), Instruction(r'\F32.\GT', r'\hex{5E}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fgt'), Instruction(r'\F32.\LE', r'\hex{5F}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fle'), Instruction(r'\F32.\GE', r'\hex{60}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fge'), Instruction(r'\F64.\EQ', r'\hex{61}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-feq'), Instruction(r'\F64.\NE', r'\hex{62}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fne'), Instruction(r'\F64.\LT', r'\hex{63}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-flt'), Instruction(r'\F64.\GT', r'\hex{64}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fgt'), Instruction(r'\F64.\LE', r'\hex{65}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fle'), Instruction(r'\F64.\GE', r'\hex{66}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fge'), Instruction(r'\I32.\CLZ', r'\hex{67}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iclz'), Instruction(r'\I32.\CTZ', r'\hex{68}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-ictz'), Instruction(r'\I32.\POPCNT', r'\hex{69}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-ipopcnt'), Instruction(r'\I32.\ADD', r'\hex{6A}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-iadd'), Instruction(r'\I32.\SUB', r'\hex{6B}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-isub'), Instruction(r'\I32.\MUL', r'\hex{6C}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-imul'), Instruction(r'\I32.\DIV\K{\_s}', r'\hex{6D}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-idiv_s'), Instruction(r'\I32.\DIV\K{\_u}', r'\hex{6E}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-idiv_u'), Instruction(r'\I32.\REM\K{\_s}', r'\hex{6F}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irem_s'), Instruction(r'\I32.\REM\K{\_u}', r'\hex{70}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irem_u'), Instruction(r'\I32.\AND', r'\hex{71}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-iand'), Instruction(r'\I32.\OR', r'\hex{72}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ior'), Instruction(r'\I32.\XOR', r'\hex{73}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ixor'), Instruction(r'\I32.\SHL', r'\hex{74}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishl'), Instruction(r'\I32.\SHR\K{\_s}', r'\hex{75}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishr_s'), Instruction(r'\I32.\SHR\K{\_u}', r'\hex{76}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishr_u'), Instruction(r'\I32.\ROTL', r'\hex{77}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irotl'), Instruction(r'\I32.\ROTR', r'\hex{78}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irotr'), Instruction(r'\I64.\CLZ', r'\hex{79}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iclz'), Instruction(r'\I64.\CTZ', r'\hex{7A}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-ictz'), Instruction(r'\I64.\POPCNT', r'\hex{7B}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-ipopcnt'), Instruction(r'\I64.\ADD', r'\hex{7C}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-iadd'), Instruction(r'\I64.\SUB', r'\hex{7D}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-isub'), Instruction(r'\I64.\MUL', r'\hex{7E}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-imul'), Instruction(r'\I64.\DIV\K{\_s}', r'\hex{7F}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-idiv_s'), Instruction(r'\I64.\DIV\K{\_u}', r'\hex{80}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-idiv_u'), Instruction(r'\I64.\REM\K{\_s}', r'\hex{81}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irem_s'), Instruction(r'\I64.\REM\K{\_u}', r'\hex{82}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irem_u'), Instruction(r'\I64.\AND', r'\hex{83}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-iand'), Instruction(r'\I64.\OR', r'\hex{84}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ior'), Instruction(r'\I64.\XOR', r'\hex{85}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ixor'), Instruction(r'\I64.\SHL', r'\hex{86}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishl'), Instruction(r'\I64.\SHR\K{\_s}', r'\hex{87}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishr_s'), Instruction(r'\I64.\SHR\K{\_u}', r'\hex{88}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishr_u'), Instruction(r'\I64.\ROTL', r'\hex{89}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irotl'), Instruction(r'\I64.\ROTR', r'\hex{8A}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irotr'), Instruction(r'\F32.\ABS', r'\hex{8B}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fabs'), Instruction(r'\F32.\NEG', r'\hex{8C}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fneg'), Instruction(r'\F32.\CEIL', r'\hex{8D}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fceil'), Instruction(r'\F32.\FLOOR', r'\hex{8E}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-ffloor'), Instruction(r'\F32.\TRUNC', r'\hex{8F}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-ftrunc'), Instruction(r'\F32.\NEAREST', r'\hex{90}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fnearest'), Instruction(r'\F32.\SQRT', r'\hex{91}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fsqrt'), Instruction(r'\F32.\ADD', r'\hex{92}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fadd'), Instruction(r'\F32.\SUB', r'\hex{93}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fsub'), Instruction(r'\F32.\MUL', r'\hex{94}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmul'), Instruction(r'\F32.\DIV', r'\hex{95}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fdiv'), Instruction(r'\F32.\FMIN', r'\hex{96}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmin'), Instruction(r'\F32.\FMAX', r'\hex{97}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmax'), Instruction(r'\F32.\COPYSIGN', r'\hex{98}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fcopysign'), Instruction(r'\F64.\ABS', r'\hex{99}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fabs'), Instruction(r'\F64.\NEG', r'\hex{9A}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fneg'), Instruction(r'\F64.\CEIL', r'\hex{9B}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fceil'), Instruction(r'\F64.\FLOOR', r'\hex{9C}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-ffloor'), Instruction(r'\F64.\TRUNC', r'\hex{9D}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-ftrunc'), Instruction(r'\F64.\NEAREST', r'\hex{9E}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fnearest'), Instruction(r'\F64.\SQRT', r'\hex{9F}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fsqrt'), Instruction(r'\F64.\ADD', r'\hex{A0}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fadd'), Instruction(r'\F64.\SUB', r'\hex{A1}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fsub'), Instruction(r'\F64.\MUL', r'\hex{A2}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmul'), Instruction(r'\F64.\DIV', r'\hex{A3}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fdiv'), Instruction(r'\F64.\FMIN', r'\hex{A4}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmin'), Instruction(r'\F64.\FMAX', r'\hex{A5}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmax'), Instruction(r'\F64.\COPYSIGN', r'\hex{A6}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fcopysign'), Instruction(r'\I32.\WRAP\K{\_}\I64', r'\hex{A7}', r'[\I64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-wrap'), Instruction(r'\I32.\TRUNC\K{\_}\F32\K{\_s}', r'\hex{A8}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), Instruction(r'\I32.\TRUNC\K{\_}\F32\K{\_u}', r'\hex{A9}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), Instruction(r'\I32.\TRUNC\K{\_}\F64\K{\_s}', r'\hex{AA}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), Instruction(r'\I32.\TRUNC\K{\_}\F64\K{\_u}', r'\hex{AB}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), Instruction(r'\I64.\EXTEND\K{\_}\I32\K{\_s}', r'\hex{AC}', r'[\I32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-extend_s'), Instruction(r'\I64.\EXTEND\K{\_}\I32\K{\_u}', r'\hex{AD}', r'[\I32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-extend_u'), Instruction(r'\I64.\TRUNC\K{\_}\F32\K{\_s}', r'\hex{AE}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), Instruction(r'\I64.\TRUNC\K{\_}\F32\K{\_u}', r'\hex{AF}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), Instruction(r'\I64.\TRUNC\K{\_}\F64\K{\_s}', r'\hex{B0}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), Instruction(r'\I64.\TRUNC\K{\_}\F64\K{\_u}', r'\hex{B1}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), Instruction(r'\F32.\CONVERT\K{\_}\I32\K{\_s}', r'\hex{B2}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), Instruction(r'\F32.\CONVERT\K{\_}\I32\K{\_u}', r'\hex{B3}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), Instruction(r'\F32.\CONVERT\K{\_}\I64\K{\_s}', r'\hex{B4}', r'[\I64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), Instruction(r'\F32.\CONVERT\K{\_}\I64\K{\_u}', r'\hex{B5}', r'[\I64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), Instruction(r'\F32.\DEMOTE\K{\_}\F64', r'\hex{B6}', r'[\F64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-demote'), Instruction(r'\F64.\CONVERT\K{\_}\I32\K{\_s}', r'\hex{B7}', r'[\I32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), Instruction(r'\F64.\CONVERT\K{\_}\I32\K{\_u}', r'\hex{B8}', r'[\I32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), Instruction(r'\F64.\CONVERT\K{\_}\I64\K{\_s}', r'\hex{B9}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), Instruction(r'\F64.\CONVERT\K{\_}\I64\K{\_u}', r'\hex{BA}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), Instruction(r'\F64.\PROMOTE\K{\_}\F32', r'\hex{BB}', r'[\F32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-promote'), Instruction(r'\I32.\REINTERPRET\K{\_}\F32', r'\hex{BC}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), Instruction(r'\I64.\REINTERPRET\K{\_}\F64', r'\hex{BD}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), Instruction(r'\F32.\REINTERPRET\K{\_}\I32', r'\hex{BE}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), Instruction(r'\F64.\REINTERPRET\K{\_}\I64', r'\hex{BF}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), Instruction(r'\I32.\EXTEND\K{8\_s}', r'\hex{C0}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I32.\EXTEND\K{16\_s}', r'\hex{C1}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I64.\EXTEND\K{8\_s}', r'\hex{C2}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I64.\EXTEND\K{16\_s}', r'\hex{C3}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I64.\EXTEND\K{32\_s}', r'\hex{C4}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(None, r'\hex{C5}'), Instruction(None, r'\hex{C6}'), Instruction(None, r'\hex{C7}'), Instruction(None, r'\hex{C8}'), Instruction(None, r'\hex{C9}'), Instruction(None, r'\hex{CA}'), Instruction(None, r'\hex{CB}'), Instruction(None, r'\hex{CC}'), Instruction(None, r'\hex{CD}'), Instruction(None, r'\hex{CE}'), Instruction(None, r'\hex{CF}'), Instruction(r'\REFNULL~t', r'\hex{D0}', r'[] \to [t]', r'valid-ref.null', r'exec-ref.null'), Instruction(r'\REFISNULL', r'\hex{D1}', r'[t] \to [\I32]', r'valid-ref.is_null', r'exec-ref.is_null'), Instruction(r'\REFFUNC~x', r'\hex{D2}', r'[] \to [\FUNCREF]', r'valid-ref.func', r'exec-ref.func'), Instruction(None, r'\hex{D3}'), Instruction(None, r'\hex{D4}'), Instruction(None, r'\hex{D5}'), Instruction(None, r'\hex{D6}'), Instruction(None, r'\hex{D7}'), Instruction(None, r'\hex{D8}'), Instruction(None, r'\hex{D9}'), Instruction(None, r'\hex{DA}'), Instruction(None, r'\hex{DB}'), Instruction(None, r'\hex{DC}'), Instruction(None, r'\hex{DD}'), Instruction(None, r'\hex{DE}'), Instruction(None, r'\hex{DF}'), Instruction(None, r'\hex{E0}'), Instruction(None, r'\hex{E1}'), Instruction(None, r'\hex{E2}'), Instruction(None, r'\hex{E3}'), Instruction(None, r'\hex{E4}'), Instruction(None, r'\hex{E5}'), Instruction(None, r'\hex{E6}'), Instruction(None, r'\hex{E7}'), Instruction(None, r'\hex{E8}'), Instruction(None, r'\hex{E9}'), Instruction(None, r'\hex{EA}'), Instruction(None, r'\hex{EB}'), Instruction(None, r'\hex{EC}'), Instruction(None, r'\hex{ED}'), Instruction(None, r'\hex{EE}'), Instruction(None, r'\hex{EF}'), Instruction(None, r'\hex{F0}'), Instruction(None, r'\hex{F1}'), Instruction(None, r'\hex{F2}'), Instruction(None, r'\hex{F3}'), Instruction(None, r'\hex{F4}'), Instruction(None, r'\hex{F5}'), Instruction(None, r'\hex{F6}'), Instruction(None, r'\hex{F7}'), Instruction(None, r'\hex{F8}'), Instruction(None, r'\hex{F9}'), Instruction(None, r'\hex{FA}'), Instruction(None, r'\hex{FB}'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}', r'\hex{FC}~\hex{00}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}', r'\hex{FC}~\hex{01}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}', r'\hex{FC}~\hex{02}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}', r'\hex{FC}~\hex{03}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), Instruction(r'\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}', r'\hex{FC}~\hex{04}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), Instruction(r'\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}', r'\hex{FC}~\hex{05}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), Instruction(r'\I64.\TRUNC\K{\_sat\_}\F64\K{\_s}', r'\hex{FC}~\hex{06}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), Instruction(r'\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}', r'\hex{FC}~\hex{07}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), Instruction(r'\MEMORYINIT', r'\hex{FC}~\hex{08}', r'[\I32~\I32~\I32] \to []', r'valid-memory.init', r'exec-memory.init'), Instruction(r'\DATADROP', r'\hex{FC}~\hex{09}', r'[] \to []', r'valid-data.drop', r'exec-data.drop'), Instruction(r'\MEMORYCOPY', r'\hex{FC}~\hex{0A}', r'[\I32~\I32~\I32] \to []', r'valid-memory.copy', r'exec-memory.copy'), Instruction(r'\MEMORYFILL', r'\hex{FC}~\hex{0B}', r'[\I32~\I32~\I32] \to []', r'valid-memory.fill', r'exec-memory.fill'), Instruction(r'\TABLEINIT', r'\hex{FC}~\hex{0C}', r'[\I32~\I32~\I32] \to []', r'valid-table.init', r'exec-table.init'), Instruction(r'\ELEMDROP', r'\hex{FC}~\hex{0D}', r'[] \to []', r'valid-elem.drop', r'exec-elem.drop'), Instruction(r'\TABLECOPY', r'\hex{FC}~\hex{0E}', r'[\I32~\I32~\I32] \to []', r'valid-table.copy', r'exec-table.copy'), Instruction(r'\TABLEGROW', r'\hex{FC}~\hex{0F}', r'[t~\I32] \to []', r'valid-table.grow', r'exec-table.grow'), Instruction(r'\TABLESIZE', r'\hex{FC}~\hex{10}', r'[] \to []', r'valid-table.size', r'exec-table.size'), Instruction(r'\TABLEFILL', r'\hex{FC}~\hex{11}', r'[\I32~t~\I32] \to []', r'valid-table.fill', r'exec-table.fill'), ] def ColumnWidth(n): return max([len(instr[n]) for instr in INSTRUCTIONS]) COLUMN_WIDTHS = [ColumnWidth(i) for i in range(len(COLUMNS))] DIVIDER = ' '.join('=' * width for width in COLUMN_WIDTHS) def Row(columns): return ' '.join(('{:%d}' % COLUMN_WIDTHS[i]).format(column) for i, column in enumerate(columns)) if __name__ == '__main__': with open(INDEX_INSTRUCTIONS_RST, 'w') as f: print(HEADER, file=f) print(DIVIDER, file=f) print(Row(COLUMNS), file=f) print(DIVIDER, file=f) for instr in INSTRUCTIONS: print(Row(instr), file=f) print(DIVIDER, file=f) ================================================ FILE: document/core/appendix/implementation.rst ================================================ .. index:: ! implementation limitations, implementation .. _impl: Implementation Limitations -------------------------- Implementations typically impose additional restrictions on a number of aspects of a WebAssembly module or execution. These may stem from: * physical resource limits, * constraints imposed by the embedder or its environment, * limitations of selected implementation strategies. This section lists allowed limitations. Where restrictions take the form of numeric limits, no minimum requirements are given, nor are the limits assumed to be concrete, fixed numbers. However, it is expected that all implementations have "reasonably" large limits to enable common applications. .. note:: A conforming implementation is not allowed to leave out individual *features*. However, designated subsets of WebAssembly may be specified in the future. Syntactic Limits ~~~~~~~~~~~~~~~~ .. index:: abstract syntax, module, type, function, table, memory, global, element, data, import, export, parameter, result, local, structured control instruction, instruction, name, Unicode, character .. _impl-syntax: Structure ......... An implementation may impose restrictions on the following dimensions of a module: * the number of :ref:`types ` in a :ref:`module ` * the number of :ref:`functions ` in a :ref:`module `, including imports * the number of :ref:`tables ` in a :ref:`module `, including imports * the number of :ref:`memories ` in a :ref:`module `, including imports * the number of :ref:`globals ` in a :ref:`module `, including imports * the number of :ref:`element segments ` in a :ref:`module ` * the number of :ref:`data segments ` in a :ref:`module ` * the number of :ref:`imports ` to a :ref:`module ` * the number of :ref:`exports ` from a :ref:`module ` * the number of parameters in a :ref:`function type ` * the number of results in a :ref:`function type ` * the number of parameters in a :ref:`block type ` * the number of results in a :ref:`block type ` * the number of :ref:`locals ` in a :ref:`function ` * the size of a :ref:`function ` body * the size of a :ref:`structured control instruction ` * the number of :ref:`structured control instructions ` in a :ref:`function ` * the nesting depth of :ref:`structured control instructions ` * the number of :ref:`label indices ` in a |brtable| instruction * the length of an :ref:`element segment ` * the length of a :ref:`data segment ` * the length of a :ref:`name ` * the range of :ref:`characters ` in a :ref:`name ` If the limits of an implementation are exceeded for a given module, then the implementation may reject the :ref:`validation `, compilation, or :ref:`instantiation ` of that module with an embedder-specific error. .. note:: The last item allows :ref:`embedders ` that operate in limited environments without support for |Unicode|_ to limit the names of :ref:`imports ` and :ref:`exports ` to common subsets like |ASCII|_. .. index:: binary format, module, section, function, code .. _impl-binary: Binary Format ............. For a module given in :ref:`binary format `, additional limitations may be imposed on the following dimensions: * the size of a :ref:`module ` * the size of any :ref:`section ` * the size of an individual function's :ref:`code ` * the number of :ref:`sections ` .. index:: text format, source text, token, identifier, character, unicode .. _impl-text: Text Format ........... For a module given in :ref:`text format `, additional limitations may be imposed on the following dimensions: * the size of the :ref:`source text ` * the size of any syntactic element * the size of an individual :ref:`token ` * the nesting depth of :ref:`folded instructions ` * the length of symbolic :ref:`identifiers ` * the range of literal :ref:`characters ` allowed in the :ref:`source text ` .. index:: validation, function .. _impl-valid: Validation ~~~~~~~~~~ An implementation may defer :ref:`validation ` of individual :ref:`functions ` until they are first :ref:`invoked `. If a function turns out to be invalid, then the invocation, and every consecutive call to the same function, results in a :ref:`trap `. .. note:: This is to allow implementations to use interpretation or just-in-time compilation for functions. The function must still be fully validated before execution of its body begins. .. index:: execution, module instance, function instance, table instance, memory instance, global instance, allocation, frame, label, value .. _impl-exec: Execution ~~~~~~~~~ Restrictions on the following dimensions may be imposed during :ref:`execution ` of a WebAssembly program: * the number of allocated :ref:`module instances ` * the number of allocated :ref:`function instances ` * the number of allocated :ref:`table instances ` * the number of allocated :ref:`memory instances ` * the number of allocated :ref:`global instances ` * the size of a :ref:`table instance ` * the size of a :ref:`memory instance ` * the number of :ref:`frames ` on the :ref:`stack ` * the number of :ref:`labels ` on the :ref:`stack ` * the number of :ref:`values ` on the :ref:`stack ` If the runtime limits of an implementation are exceeded during execution of a computation, then it may terminate that computation and report an embedder-specific error to the invoking code. Some of the above limits may already be verified during instantiation, in which case an implementation may report exceedance in the same manner as for :ref:`syntactic limits `. .. note:: Concrete limits are usually not fixed but may be dependent on specifics, interdependent, vary over time, or depend on other implementation- or embedder-specific situations or events. ================================================ FILE: document/core/appendix/index-instructions.rst ================================================ .. DO NOT EDIT: This file is auto-generated by the gen-index-instructions.py script. .. index:: instruction .. _index-instr: Index of Instructions --------------------- ========================================= ========================= ============================================= ======================================= =============================================================== Instruction Binary Opcode Type Validation Execution ========================================= ========================= ============================================= ======================================= =============================================================== :math:`\UNREACHABLE` :math:`\hex{00}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\NOP` :math:`\hex{01}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` :math:`\BLOCK~\X{bt}` :math:`\hex{02}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\LOOP~\X{bt}` :math:`\hex{03}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\IF~\X{bt}` :math:`\hex{04}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\ELSE` :math:`\hex{05}` (reserved) :math:`\hex{06}` (reserved) :math:`\hex{07}` (reserved) :math:`\hex{08}` (reserved) :math:`\hex{09}` (reserved) :math:`\hex{0A}` :math:`\END` :math:`\hex{0B}` :math:`\BR~l` :math:`\hex{0C}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\BRIF~l` :math:`\hex{0D}` :math:`[t^\ast~\I32] \to [t^\ast]` :ref:`validation ` :ref:`execution ` :math:`\BRTABLE~l^\ast~l` :math:`\hex{0E}` :math:`[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\RETURN` :math:`\hex{0F}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\CALL~x` :math:`\hex{10}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` :math:`\CALLINDIRECT~x~y` :math:`\hex{11}` :math:`[t_1^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{12}` (reserved) :math:`\hex{13}` (reserved) :math:`\hex{14}` (reserved) :math:`\hex{15}` (reserved) :math:`\hex{16}` (reserved) :math:`\hex{17}` (reserved) :math:`\hex{18}` (reserved) :math:`\hex{19}` :math:`\DROP` :math:`\hex{1A}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` :math:`\SELECT` :math:`\hex{1B}` :math:`[t~t~\I32] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\SELECT~t` :math:`\hex{1C}` :math:`[t~t~\I32] \to [t]` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{1D}` (reserved) :math:`\hex{1E}` (reserved) :math:`\hex{1F}` :math:`\LOCALGET~x` :math:`\hex{20}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\LOCALSET~x` :math:`\hex{21}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` :math:`\LOCALTEE~x` :math:`\hex{22}` :math:`[t] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\GLOBALGET~x` :math:`\hex{23}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\GLOBALSET~x` :math:`\hex{24}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLEGET~x` :math:`\hex{25}` :math:`[\I32] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\TABLESET~x` :math:`\hex{26}` :math:`[\I32~t] \to []` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{27}` :math:`\I32.\LOAD~\memarg` :math:`\hex{28}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD~\memarg` :math:`\hex{29}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\F32.\LOAD~\memarg` :math:`\hex{2A}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution ` :math:`\F64.\LOAD~\memarg` :math:`\hex{2B}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution ` :math:`\I32.\LOAD\K{8\_s}~\memarg` :math:`\hex{2C}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I32.\LOAD\K{8\_u}~\memarg` :math:`\hex{2D}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I32.\LOAD\K{16\_s}~\memarg` :math:`\hex{2E}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I32.\LOAD\K{16\_u}~\memarg` :math:`\hex{2F}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{8\_s}~\memarg` :math:`\hex{30}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{8\_u}~\memarg` :math:`\hex{31}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{16\_s}~\memarg` :math:`\hex{32}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{16\_u}~\memarg` :math:`\hex{33}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{32\_s}~\memarg` :math:`\hex{34}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I64.\LOAD\K{32\_u}~\memarg` :math:`\hex{35}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\I32.\STORE~\memarg` :math:`\hex{36}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\I64.\STORE~\memarg` :math:`\hex{37}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` :math:`\F32.\STORE~\memarg` :math:`\hex{38}` :math:`[\I32~\F32] \to []` :ref:`validation ` :ref:`execution ` :math:`\F64.\STORE~\memarg` :math:`\hex{39}` :math:`[\I32~\F64] \to []` :ref:`validation ` :ref:`execution ` :math:`\I32.\STORE\K{8}~\memarg` :math:`\hex{3A}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\I32.\STORE\K{16}~\memarg` :math:`\hex{3B}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\I64.\STORE\K{8}~\memarg` :math:`\hex{3C}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` :math:`\I64.\STORE\K{16}~\memarg` :math:`\hex{3D}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` :math:`\I64.\STORE\K{32}~\memarg` :math:`\hex{3E}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` :math:`\MEMORYSIZE` :math:`\hex{3F}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\MEMORYGROW` :math:`\hex{40}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I32.\CONST~\i32` :math:`\hex{41}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\I64.\CONST~\i64` :math:`\hex{42}` :math:`[] \to [\I64]` :ref:`validation ` :ref:`execution ` :math:`\F32.\CONST~\f32` :math:`\hex{43}` :math:`[] \to [\F32]` :ref:`validation ` :ref:`execution ` :math:`\F64.\CONST~\f64` :math:`\hex{44}` :math:`[] \to [\F64]` :ref:`validation ` :ref:`execution ` :math:`\I32.\EQZ` :math:`\hex{45}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\EQ` :math:`\hex{46}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\NE` :math:`\hex{47}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\LT\K{\_s}` :math:`\hex{48}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\LT\K{\_u}` :math:`\hex{49}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\GT\K{\_s}` :math:`\hex{4A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\GT\K{\_u}` :math:`\hex{4B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\LE\K{\_s}` :math:`\hex{4C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\LE\K{\_u}` :math:`\hex{4D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\GE\K{\_s}` :math:`\hex{4E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\GE\K{\_u}` :math:`\hex{4F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EQZ` :math:`\hex{50}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EQ` :math:`\hex{51}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\NE` :math:`\hex{52}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\LT\K{\_s}` :math:`\hex{53}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\LT\K{\_u}` :math:`\hex{54}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\GT\K{\_s}` :math:`\hex{55}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\GT\K{\_u}` :math:`\hex{56}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\LE\K{\_s}` :math:`\hex{57}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\LE\K{\_u}` :math:`\hex{58}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\GE\K{\_s}` :math:`\hex{59}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\GE\K{\_u}` :math:`\hex{5A}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\EQ` :math:`\hex{5B}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\NE` :math:`\hex{5C}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\LT` :math:`\hex{5D}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\GT` :math:`\hex{5E}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\LE` :math:`\hex{5F}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\GE` :math:`\hex{60}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\EQ` :math:`\hex{61}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\NE` :math:`\hex{62}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\LT` :math:`\hex{63}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\GT` :math:`\hex{64}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\LE` :math:`\hex{65}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\GE` :math:`\hex{66}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\CLZ` :math:`\hex{67}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\CTZ` :math:`\hex{68}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\POPCNT` :math:`\hex{69}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\ADD` :math:`\hex{6A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\SUB` :math:`\hex{6B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\MUL` :math:`\hex{6C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\DIV\K{\_s}` :math:`\hex{6D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\DIV\K{\_u}` :math:`\hex{6E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\REM\K{\_s}` :math:`\hex{6F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\REM\K{\_u}` :math:`\hex{70}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\AND` :math:`\hex{71}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\OR` :math:`\hex{72}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\XOR` :math:`\hex{73}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\SHL` :math:`\hex{74}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\SHR\K{\_s}` :math:`\hex{75}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\SHR\K{\_u}` :math:`\hex{76}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\ROTL` :math:`\hex{77}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\ROTR` :math:`\hex{78}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\CLZ` :math:`\hex{79}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\CTZ` :math:`\hex{7A}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\POPCNT` :math:`\hex{7B}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\ADD` :math:`\hex{7C}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\SUB` :math:`\hex{7D}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\MUL` :math:`\hex{7E}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\DIV\K{\_s}` :math:`\hex{7F}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\DIV\K{\_u}` :math:`\hex{80}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\REM\K{\_s}` :math:`\hex{81}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\REM\K{\_u}` :math:`\hex{82}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\AND` :math:`\hex{83}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\OR` :math:`\hex{84}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\XOR` :math:`\hex{85}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\SHL` :math:`\hex{86}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\SHR\K{\_s}` :math:`\hex{87}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\SHR\K{\_u}` :math:`\hex{88}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\ROTL` :math:`\hex{89}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\ROTR` :math:`\hex{8A}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\ABS` :math:`\hex{8B}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\NEG` :math:`\hex{8C}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\CEIL` :math:`\hex{8D}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\FLOOR` :math:`\hex{8E}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\TRUNC` :math:`\hex{8F}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\NEAREST` :math:`\hex{90}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\SQRT` :math:`\hex{91}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\ADD` :math:`\hex{92}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\SUB` :math:`\hex{93}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\MUL` :math:`\hex{94}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\DIV` :math:`\hex{95}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\FMIN` :math:`\hex{96}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\FMAX` :math:`\hex{97}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\COPYSIGN` :math:`\hex{98}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\ABS` :math:`\hex{99}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\NEG` :math:`\hex{9A}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\CEIL` :math:`\hex{9B}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\FLOOR` :math:`\hex{9C}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\TRUNC` :math:`\hex{9D}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\NEAREST` :math:`\hex{9E}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\SQRT` :math:`\hex{9F}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\ADD` :math:`\hex{A0}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\SUB` :math:`\hex{A1}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\MUL` :math:`\hex{A2}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\DIV` :math:`\hex{A3}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\FMIN` :math:`\hex{A4}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\FMAX` :math:`\hex{A5}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\COPYSIGN` :math:`\hex{A6}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\WRAP\K{\_}\I64` :math:`\hex{A7}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{A8}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{A9}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{AA}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{AB}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{\_}\I32\K{\_s}` :math:`\hex{AC}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{\_}\I32\K{\_u}` :math:`\hex{AD}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{AE}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{AF}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{B0}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{B1}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B2}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B3}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B4}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{B5}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\DEMOTE\K{\_}\F64` :math:`\hex{B6}` :math:`[\F64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B7}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B8}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B9}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{BA}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\PROMOTE\K{\_}\F32` :math:`\hex{BB}` :math:`[\F32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\REINTERPRET\K{\_}\F32` :math:`\hex{BC}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\REINTERPRET\K{\_}\F64` :math:`\hex{BD}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F32.\REINTERPRET\K{\_}\I32` :math:`\hex{BE}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\F64.\REINTERPRET\K{\_}\I64` :math:`\hex{BF}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\EXTEND\K{8\_s}` :math:`\hex{C0}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\EXTEND\K{16\_s}` :math:`\hex{C1}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{8\_s}` :math:`\hex{C2}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{16\_s}` :math:`\hex{C3}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{32\_s}` :math:`\hex{C4}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` (reserved) :math:`\hex{C5}` (reserved) :math:`\hex{C6}` (reserved) :math:`\hex{C7}` (reserved) :math:`\hex{C8}` (reserved) :math:`\hex{C9}` (reserved) :math:`\hex{CA}` (reserved) :math:`\hex{CB}` (reserved) :math:`\hex{CC}` (reserved) :math:`\hex{CD}` (reserved) :math:`\hex{CE}` (reserved) :math:`\hex{CF}` :math:`\REFNULL~t` :math:`\hex{D0}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` :math:`\REFISNULL` :math:`\hex{D1}` :math:`[t] \to [\I32]` :ref:`validation ` :ref:`execution ` :math:`\REFFUNC~x` :math:`\hex{D2}` :math:`[] \to [\FUNCREF]` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{D3}` (reserved) :math:`\hex{D4}` (reserved) :math:`\hex{D5}` (reserved) :math:`\hex{D6}` (reserved) :math:`\hex{D7}` (reserved) :math:`\hex{D8}` (reserved) :math:`\hex{D9}` (reserved) :math:`\hex{DA}` (reserved) :math:`\hex{DB}` (reserved) :math:`\hex{DC}` (reserved) :math:`\hex{DD}` (reserved) :math:`\hex{DE}` (reserved) :math:`\hex{DF}` (reserved) :math:`\hex{E0}` (reserved) :math:`\hex{E1}` (reserved) :math:`\hex{E2}` (reserved) :math:`\hex{E3}` (reserved) :math:`\hex{E4}` (reserved) :math:`\hex{E5}` (reserved) :math:`\hex{E6}` (reserved) :math:`\hex{E7}` (reserved) :math:`\hex{E8}` (reserved) :math:`\hex{E9}` (reserved) :math:`\hex{EA}` (reserved) :math:`\hex{EB}` (reserved) :math:`\hex{EC}` (reserved) :math:`\hex{ED}` (reserved) :math:`\hex{EE}` (reserved) :math:`\hex{EF}` (reserved) :math:`\hex{F0}` (reserved) :math:`\hex{F1}` (reserved) :math:`\hex{F2}` (reserved) :math:`\hex{F3}` (reserved) :math:`\hex{F4}` (reserved) :math:`\hex{F5}` (reserved) :math:`\hex{F6}` (reserved) :math:`\hex{F7}` (reserved) :math:`\hex{F8}` (reserved) :math:`\hex{F9}` (reserved) :math:`\hex{FA}` (reserved) :math:`\hex{FB}` :math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}` :math:`\hex{FC}~\hex{00}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}` :math:`\hex{FC}~\hex{01}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}` :math:`\hex{FC}~\hex{02}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~\hex{03}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}` :math:`\hex{FC}~\hex{04}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}` :math:`\hex{FC}~\hex{05}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_s}` :math:`\hex{FC}~\hex{06}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~\hex{07}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\MEMORYINIT` :math:`\hex{FC}~\hex{08}` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\DATADROP` :math:`\hex{FC}~\hex{09}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` :math:`\MEMORYCOPY` :math:`\hex{FC}~\hex{0A}` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\MEMORYFILL` :math:`\hex{FC}~\hex{0B}` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLEINIT` :math:`\hex{FC}~\hex{0C}` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\ELEMDROP` :math:`\hex{FC}~\hex{0D}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLECOPY` :math:`\hex{FC}~\hex{0E}` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLEGROW` :math:`\hex{FC}~\hex{0F}` :math:`[t~\I32] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLESIZE` :math:`\hex{FC}~\hex{10}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` :math:`\TABLEFILL` :math:`\hex{FC}~\hex{11}` :math:`[\I32~t~\I32] \to []` :ref:`validation ` :ref:`execution ` ========================================= ========================= ============================================= ======================================= =============================================================== ================================================ FILE: document/core/appendix/index-rules.rst ================================================ .. _index-rules: Index of Semantic Rules ----------------------- .. index:: validation .. _index-valid: Typing of Static Constructs ~~~~~~~~~~~~~~~~~~~~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`Limits ` :math:`\vdashlimits \limits : k` :ref:`Function type ` :math:`\vdashfunctype \functype \ok` :ref:`Block type ` :math:`\vdashblocktype \blocktype \ok` :ref:`Table type ` :math:`\vdashtabletype \tabletype \ok` :ref:`Memory type ` :math:`\vdashmemtype \memtype \ok` :ref:`Global type ` :math:`\vdashglobaltype \globaltype \ok` :ref:`External type ` :math:`\vdashexterntype \externtype \ok` :ref:`Instruction ` :math:`S;C \vdashinstr \instr : \stacktype` :ref:`Instruction sequence ` :math:`S;C \vdashinstrseq \instr^\ast : \stacktype` :ref:`Expression ` :math:`C \vdashexpr \expr : \resulttype` :ref:`Function ` :math:`C \vdashfunc \func : \functype` :ref:`Table ` :math:`C \vdashtable \table : \tabletype` :ref:`Memory ` :math:`C \vdashmem \mem : \memtype` :ref:`Global ` :math:`C \vdashglobal \global : \globaltype` :ref:`Element segment ` :math:`C \vdashelem \elem : \reftype` :ref:`Element mode ` :math:`C \vdashelemmode \elemmode : \reftype` :ref:`Data segment ` :math:`C \vdashdata \data \ok` :ref:`Data mode ` :math:`C \vdashdatamode \datamode \ok` :ref:`Start function ` :math:`C \vdashstart \start \ok` :ref:`Export ` :math:`C \vdashexport \export : \externtype` :ref:`Export description ` :math:`C \vdashexportdesc \exportdesc : \externtype` :ref:`Import ` :math:`C \vdashimport \import : \externtype` :ref:`Import description ` :math:`C \vdashimportdesc \importdesc : \externtype` :ref:`Module ` :math:`\vdashmodule \module : \externtype^\ast \to \externtype^\ast` =============================================== =============================================================================== .. index:: runtime Typing of Runtime Constructs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`Value ` :math:`S \vdashval \val : \valtype` :ref:`Result ` :math:`S \vdashresult \result : \resulttype` :ref:`External value ` :math:`S \vdashexternval \externval : \externtype` :ref:`Function instance ` :math:`S \vdashfuncinst \funcinst : \functype` :ref:`Table instance ` :math:`S \vdashtableinst \tableinst : \tabletype` :ref:`Memory instance ` :math:`S \vdashmeminst \meminst : \memtype` :ref:`Global instance ` :math:`S \vdashglobalinst \globalinst : \globaltype` :ref:`Element instance ` :math:`S \vdasheleminst \eleminst \ok` :ref:`Data instance ` :math:`S \vdashdatainst \datainst \ok` :ref:`Export instance ` :math:`S \vdashexportinst \exportinst \ok` :ref:`Module instance ` :math:`S \vdashmoduleinst \moduleinst : C` :ref:`Store ` :math:`\vdashstore \store \ok` :ref:`Configuration ` :math:`\vdashconfig \config \ok` :ref:`Thread ` :math:`S;\resulttype^? \vdashthread \thread : \resulttype` :ref:`Frame ` :math:`S \vdashframe \frame : C` =============================================== =============================================================================== Constantness ~~~~~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`Constant expression ` :math:`C \vdashexprconst \expr \const` :ref:`Constant instruction ` :math:`C \vdashinstrconst \instr \const` =============================================== =============================================================================== Matching ~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`External type ` :math:`\vdashexterntypematch \externtype_1 \matchesexterntype \externtype_2` :ref:`Limits ` :math:`\vdashlimitsmatch \limits_1 \matcheslimits \limits_2` =============================================== =============================================================================== Store Extension ~~~~~~~~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`Function instance ` :math:`\vdashfuncinstextends \funcinst_1 \extendsto \funcinst_2` :ref:`Table instance ` :math:`\vdashtableinstextends \tableinst_1 \extendsto \tableinst_2` :ref:`Memory instance ` :math:`\vdashmeminstextends \meminst_1 \extendsto \meminst_2` :ref:`Global instance ` :math:`\vdashglobalinstextends \globalinst_1 \extendsto \globalinst_2` :ref:`Element instance ` :math:`\vdasheleminstextends \eleminst_1 \extendsto \eleminst_2` :ref:`Data instance ` :math:`\vdashdatainstextends \datainst_1 \extendsto \datainst_2` :ref:`Store ` :math:`\vdashstoreextends \store_1 \extendsto \store_2` =============================================== =============================================================================== Execution ~~~~~~~~~ =============================================== =============================================================================== Construct Judgement =============================================== =============================================================================== :ref:`Instruction ` :math:`S;F;\instr^\ast \stepto S';F';{\instr'}^\ast` :ref:`Expression ` :math:`S;F;\expr \stepto S';F';\expr'` =============================================== =============================================================================== ================================================ FILE: document/core/appendix/index-types.rst ================================================ .. index:: type .. _index-type: Index of Types -------------- ======================================== =========================================== =============================================================================== Category Constructor Binary Opcode ======================================== =========================================== =============================================================================== :ref:`Type index ` :math:`x` (positive number as |Bs32| or |Bu32|) :ref:`Number type ` |I32| :math:`\hex{7F}` (-1 as |Bs7|) :ref:`Number type ` |I64| :math:`\hex{7E}` (-2 as |Bs7|) :ref:`Number type ` |F32| :math:`\hex{7D}` (-3 as |Bs7|) :ref:`Number type ` |F64| :math:`\hex{7C}` (-4 as |Bs7|) (reserved) :math:`\hex{7B}` .. :math:`\hex{71}` :ref:`Reference type ` |FUNCREF| :math:`\hex{70}` (-16 as |Bs7|) :ref:`Reference type ` |EXTERNREF| :math:`\hex{6F}` (-17 as |Bs7|) (reserved) :math:`\hex{6E}` .. :math:`\hex{61}` :ref:`Function type ` :math:`[\valtype^\ast] \to [\valtype^\ast]` :math:`\hex{60}` (-32 as |Bs7|) (reserved) :math:`\hex{5F}` .. :math:`\hex{41}` :ref:`Result type ` :math:`[\epsilon]` :math:`\hex{40}` (-64 as |Bs7|) :ref:`Table type ` :math:`\limits~\reftype` (none) :ref:`Memory type ` :math:`\limits` (none) :ref:`Global type ` :math:`\mut~\valtype` (none) ======================================== =========================================== =============================================================================== ================================================ FILE: document/core/appendix/index.rst ================================================ .. _appendix: Appendix ======== .. toctree:: :maxdepth: 2 embedding implementation algorithm custom properties .. only:: singlehtml .. toctree:: index-types index-instructions index-rules ================================================ FILE: document/core/appendix/properties.rst ================================================ .. index:: ! soundness, type system .. _soundness: Soundness --------- The :ref:`type system ` of WebAssembly is *sound*, implying both *type safety* and *memory safety* with respect to the WebAssembly semantics. For example: * All types declared and derived during validation are respected at run time; e.g., every :ref:`local ` or :ref:`global ` variable will only contain type-correct values, every :ref:`instruction ` will only be applied to operands of the expected type, and every :ref:`function ` :ref:`invocation ` always evaluates to a result of the right type (if it does not :ref:`trap ` or diverge). * No memory location will be read or written except those explicitly defined by the program, i.e., as a :ref:`local `, a :ref:`global `, an element in a :ref:`table `, or a location within a linear :ref:`memory `. * There is no undefined behavior, i.e., the :ref:`execution rules ` cover all possible cases that can occur in a :ref:`valid ` program, and the rules are mutually consistent. Soundness also is instrumental in ensuring additional properties, most notably, *encapsulation* of function and module scopes: no :ref:`locals ` can be accessed outside their own function and no :ref:`module ` components can be accessed outside their own module unless they are explicitly :ref:`exported ` or :ref:`imported `. The typing rules defining WebAssembly :ref:`validation ` only cover the *static* components of a WebAssembly program. In order to state and prove soundness precisely, the typing rules must be extended to the *dynamic* components of the abstract :ref:`runtime `, that is, the :ref:`store `, :ref:`configurations `, and :ref:`administrative instructions `. [#cite-pldi2017]_ .. index:: value, value type, result, result type, trap .. _valid-result: Results ~~~~~~~ :ref:`Results ` can be classified by :ref:`result types ` as follows. :ref:`Results ` :math:`\val^\ast` ................................................ * For each :ref:`value ` :math:`\val_i` in :math:`\val^\ast`: * The value :math:`\val_i` is :ref:`valid ` with some :ref:`value type ` :math:`t_i`. * Let :math:`t^\ast` be the concatenation of all :math:`t_i`. * Then the result is valid with :ref:`result type ` :math:`[t^\ast]`. .. math:: \frac{ (S \vdashval \val : t)^\ast }{ S \vdashresult \val^\ast : [t^\ast] } :ref:`Results ` :math:`\TRAP` ............................................ * The result is valid with :ref:`result type ` :math:`[t^\ast]`, for any sequence :math:`t^\ast` of :ref:`value types `. .. math:: \frac{ }{ S \vdashresult \TRAP : [t^\ast] } .. _module-context: .. _valid-store: Store Validity ~~~~~~~~~~~~~~ The following typing rules specify when a runtime :ref:`store ` :math:`S` is *valid*. A valid store must consist of :ref:`function `, :ref:`table `, :ref:`memory `, :ref:`global `, and :ref:`module ` instances that are themselves valid, relative to :math:`S`. To that end, each kind of instance is classified by a respective :ref:`function `, :ref:`table `, :ref:`memory `, or :ref:`global ` type. Module instances are classified by *module contexts*, which are regular :ref:`contexts ` repurposed as module types describing the :ref:`index spaces ` defined by a module. .. index:: store, function instance, table instance, memory instance, global instance, function type, table type, memory type, global type :ref:`Store ` :math:`S` ..................................... * Each :ref:`function instance ` :math:`\funcinst_i` in :math:`S.\SFUNCS` must be :ref:`valid ` with some :ref:`function type ` :math:`\functype_i`. * Each :ref:`table instance ` :math:`\tableinst_i` in :math:`S.\STABLES` must be :ref:`valid ` with some :ref:`table type ` :math:`\tabletype_i`. * Each :ref:`memory instance ` :math:`\meminst_i` in :math:`S.\SMEMS` must be :ref:`valid ` with some :ref:`memory type ` :math:`\memtype_i`. * Each :ref:`global instance ` :math:`\globalinst_i` in :math:`S.\SGLOBALS` must be :ref:`valid ` with some :ref:`global type ` :math:`\globaltype_i`. * Each :ref:`element instance ` :math:`\eleminst_i` in :math:`S.\SELEMS` must be :ref:`valid `. * Each :ref:`data instance ` :math:`\datainst_i` in :math:`S.\SDATAS` must be :ref:`valid `. * Then the store is valid. .. math:: ~\\[-1ex] \frac{ \begin{array}{@{}c@{}} (S \vdashfuncinst \funcinst : \functype)^\ast \qquad (S \vdashtableinst \tableinst : \tabletype)^\ast \\ (S \vdashmeminst \meminst : \memtype)^\ast \qquad (S \vdashglobalinst \globalinst : \globaltype)^\ast \\ (S \vdasheleminst \eleminst \ok)^\ast \qquad (S \vdashdatainst \datainst \ok)^\ast \\ S = \{ \SFUNCS~\funcinst^\ast, \STABLES~\tableinst^\ast, \SMEMS~\meminst^\ast, \SGLOBALS~\globalinst^\ast, \SELEMS~\eleminst^\ast, \SDATAS~\datainst^\ast \} \end{array} }{ \vdashstore S \ok } .. index:: function type, function instance .. _valid-funcinst: :ref:`Function Instances ` :math:`\{\FITYPE~\functype, \FIMODULE~\moduleinst, \FICODE~\func\}` ....................................................................................................................... * The :ref:`function type ` :math:`\functype` must be :ref:`valid `. * The :ref:`module instance ` :math:`\moduleinst` must be :ref:`valid ` with some :ref:`context ` :math:`C`. * Under :ref:`context ` :math:`C`, the :ref:`function ` :math:`\func` must be :ref:`valid ` with :ref:`function type ` :math:`\functype`. * Then the function instance is valid with :ref:`function type ` :math:`\functype`. .. math:: \frac{ \vdashfunctype \functype \ok \qquad S \vdashmoduleinst \moduleinst : C \qquad C \vdashfunc \func : \functype }{ S \vdashfuncinst \{\FITYPE~\functype, \FIMODULE~\moduleinst, \FICODE~\func\} : \functype } .. index:: function type, function instance, host function .. _valid-hostfuncinst: :ref:`Host Function Instances ` :math:`\{\FITYPE~\functype, \FIHOSTCODE~\X{hf}\}` .................................................................................................. * The :ref:`function type ` :math:`\functype` must be :ref:`valid `. * Let :math:`[t_1^\ast] \to [t_2^\ast]` be the :ref:`function type ` :math:`\functype`. * For every :ref:`valid ` :ref:`store ` :math:`S_1` :ref:`extending ` :math:`S` and every sequence :math:`\val^\ast` of :ref:`values ` whose :ref:`types ` coincide with :math:`t_1^\ast`: * :ref:`Executing ` :math:`\X{hf}` in store :math:`S_1` with arguments :math:`\val^\ast` has a non-empty set of possible outcomes. * For every element :math:`R` of this set: * Either :math:`R` must be :math:`\bot` (i.e., divergence). * Or :math:`R` consists of a :ref:`valid ` :ref:`store ` :math:`S_2` :ref:`extending ` :math:`S_1` and a :ref:`result ` :math:`\result` whose :ref:`type ` coincides with :math:`[t_2^\ast]`. * Then the function instance is valid with :ref:`function type ` :math:`\functype`. .. math:: \frac{ \begin{array}[b]{@{}l@{}} \vdashfunctype [t_1^\ast] \to [t_2^\ast] \ok \\ \end{array} \quad \begin{array}[b]{@{}l@{}} \forall S_1, \val^\ast,~ {\vdashstore S_1 \ok} \wedge {\vdashstoreextends S \extendsto S_1} \wedge {S_1 \vdashresult \val^\ast : [t_1^\ast]} \Longrightarrow {} \\ \qquad \X{hf}(S_1; \val^\ast) \supset \emptyset \wedge {} \\ \qquad \forall R \in \X{hf}(S_1; \val^\ast),~ R = \bot \vee {} \\ \qquad\qquad \exists S_2, \result,~ {\vdashstore S_2 \ok} \wedge {\vdashstoreextends S_1 \extendsto S_2} \wedge {S_2 \vdashresult \result : [t_2^\ast]} \wedge R = (S_2; \result) \end{array} }{ S \vdashfuncinst \{\FITYPE~[t_1^\ast] \to [t_2^\ast], \FIHOSTCODE~\X{hf}\} : [t_1^\ast] \to [t_2^\ast] } .. note:: This rule states that, if appropriate pre-conditions about store and arguments are satisfied, then executing the host function must satisfy appropriate post-conditions about store and results. The post-conditions match the ones in the :ref:`execution rule ` for invoking host functions. Any store under which the function is invoked is assumed to be an extension of the current store. That way, the function itself is able to make sufficient assumptions about future stores. .. index:: table type, table instance, limits, function address .. _valid-tableinst: :ref:`Table Instances ` :math:`\{ \TITYPE~(\limits~t), \TIELEM~\reff^\ast \}` ............................................................................................... * The :ref:`table type ` :math:`\limits~t` must be :ref:`valid `. * The length of :math:`\reff^\ast` must equal :math:`\limits.\LMIN`. * For each :ref:`reference ` :math:`\reff_i` in the table's elements :math:`\reff^n`: * The :ref:`reference ` :math:`\reff_i` must be :ref:`valid ` with :ref:`reference type ` :math:`t`. * Then the table instance is valid with :ref:`table type ` :math:`\limits~t`. .. math:: \frac{ \vdashtabletype \limits~t \ok \qquad n = \limits.\LMIN \qquad (S \vdash \reff : t)^n }{ S \vdashtableinst \{ \TITYPE~(\limits~t), \TIELEM~\reff^n \} : \limits~t } .. index:: memory type, memory instance, limits, byte .. _valid-meminst: :ref:`Memory Instances ` :math:`\{ \MITYPE~\limits, \MIDATA~b^\ast \}` ...................................................................................... * The :ref:`memory type ` :math:`\{\LMIN~n, \LMAX~m^?\}` must be :ref:`valid `. * The length of :math:`b^\ast` must equal :math:`\limits.\LMIN` multiplied by the :ref:`page size ` :math:`64\,\F{Ki}`. * Then the memory instance is valid with :ref:`memory type ` :math:`\limits`. .. math:: \frac{ \vdashmemtype \limits \ok \qquad n = \limits.\LMIN \cdot 64\,\F{Ki} }{ S \vdashmeminst \{ \MITYPE~\limits, \MIDATA~b^n \} : \limits } .. index:: global type, global instance, value, mutability .. _valid-globalinst: :ref:`Global Instances ` :math:`\{ \GITYPE~(\mut~t), \GIVALUE~\val \}` ......................................................................................... * The :ref:`global type ` :math:`\mut~t` must be :ref:`valid `. * The :ref:`value ` :math:`\val` must be :ref:`valid ` with :ref:`value type ` :math:`t`. * Then the global instance is valid with :ref:`global type ` :math:`\mut~t`. .. math:: \frac{ \vdashglobaltype \mut~t \ok \qquad S \vdashval \val : t }{ S \vdashglobalinst \{ \GITYPE~(\mut~t), \GIVALUE~\val \} : \mut~t } .. index:: element instance, reference .. _valid-eleminst: :ref:`Element Instances ` :math:`\{ \EIELEM~\X{fa}^\ast \}` ............................................................................ * For each :ref:`reference ` :math:`\reff_i` in the elements :math:`\reff^n`: * The :ref:`reference ` :math:`\reff_i` must be :ref:`valid ` with :ref:`reference type ` :math:`t`. * Then the table instance is valid. .. math:: \frac{ (S \vdash \reff : t)^\ast }{ S \vdasheleminst \{ \EITYPE~t, \EIELEM~\reff^\ast \} \ok } .. index:: data instance, byte .. _valid-datainst: :ref:`Data Instances ` :math:`\{ \DIDATA~b^\ast \}` .................................................................... * The data instance is valid. .. math:: \frac{ }{ S \vdashdatainst \{ \DIDATA~b^\ast \} \ok } .. index:: external type, export instance, name, external value .. _valid-exportinst: :ref:`Export Instances ` :math:`\{ \EINAME~\name, \EIVALUE~\externval \}` ....................................................................................................... * The :ref:`external value ` :math:`\externval` must be :ref:`valid ` with some :ref:`external type ` :math:`\externtype`. * Then the export instance is valid. .. math:: \frac{ S \vdashexternval \externval : \externtype }{ S \vdashexportinst \{ \EINAME~\name, \EIVALUE~\externval \} \ok } .. index:: module instance, context .. _valid-moduleinst: :ref:`Module Instances ` :math:`\moduleinst` ............................................................... * Each :ref:`function type ` :math:`\functype_i` in :math:`\moduleinst.\MITYPES` must be :ref:`valid `. * For each :ref:`function address ` :math:`\funcaddr_i` in :math:`\moduleinst.\MIFUNCS`, the :ref:`external value ` :math:`\EVFUNC~\funcaddr_i` must be :ref:`valid ` with some :ref:`external type ` :math:`\ETFUNC~\functype'_i`. * For each :ref:`table address ` :math:`\tableaddr_i` in :math:`\moduleinst.\MITABLES`, the :ref:`external value ` :math:`\EVTABLE~\tableaddr_i` must be :ref:`valid ` with some :ref:`external type ` :math:`\ETTABLE~\tabletype_i`. * For each :ref:`memory address ` :math:`\memaddr_i` in :math:`\moduleinst.\MIMEMS`, the :ref:`external value ` :math:`\EVMEM~\memaddr_i` must be :ref:`valid ` with some :ref:`external type ` :math:`\ETMEM~\memtype_i`. * For each :ref:`global address ` :math:`\globaladdr_i` in :math:`\moduleinst.\MIGLOBALS`, the :ref:`external value ` :math:`\EVGLOBAL~\globaladdr_i` must be :ref:`valid ` with some :ref:`external type ` :math:`\ETGLOBAL~\globaltype_i`. * For each :ref:`element address ` :math:`\elemaddr_i` in :math:`\moduleinst.\MIELEMS`, the :ref:`element instance ` :math:`S.\SELEMS[\elemaddr_i]` must be :ref:`valid `. * For each :ref:`data address ` :math:`\dataaddr_i` in :math:`\moduleinst.\MIDATAS`, the :ref:`data instance ` :math:`S.\SDATAS[\dataaddr_i]` must be :ref:`valid `. * Each :ref:`export instance ` :math:`\exportinst_i` in :math:`\moduleinst.\MIEXPORTS` must be :ref:`valid `. * For each :ref:`export instance ` :math:`\exportinst_i` in :math:`\moduleinst.\MIEXPORTS`, the :ref:`name ` :math:`\exportinst_i.\EINAME` must be different from any other name occurring in :math:`\moduleinst.\MIEXPORTS`. * Let :math:`{\functype'}^\ast` be the concatenation of all :math:`\functype'_i` in order. * Let :math:`\tabletype^\ast` be the concatenation of all :math:`\tabletype_i` in order. * Let :math:`\memtype^\ast` be the concatenation of all :math:`\memtype_i` in order. * Let :math:`\globaltype^\ast` be the concatenation of all :math:`\globaltype_i` in order. * Then the module instance is valid with :ref:`context ` :math:`\{\CTYPES~\functype^\ast, \CFUNCS~{\functype'}^\ast, \CTABLES~\tabletype^\ast, \CMEMS~\memtype^\ast, \CGLOBALS~\globaltype^\ast\}`. .. math:: ~\\[-1ex] \frac{ \begin{array}{@{}c@{}} (\vdashfunctype \functype \ok)^\ast \\ (S \vdashexternval \EVFUNC~\funcaddr : \ETFUNC~\functype')^\ast \qquad (S \vdashexternval \EVTABLE~\tableaddr : \ETTABLE~\tabletype)^\ast \\ (S \vdashexternval \EVMEM~\memaddr : \ETMEM~\memtype)^\ast \qquad (S \vdashexternval \EVGLOBAL~\globaladdr : \ETGLOBAL~\globaltype)^\ast \\ (S \vdasheleminst S.\SELEMS[\elemaddr] \ok)^\ast \qquad (S \vdashdatainst S.\SDATAS[\dataaddr] \ok)^\ast \\ (S \vdashexportinst \exportinst \ok)^\ast \qquad (\exportinst.\EINAME)^\ast ~\mbox{disjoint} \end{array} }{ S \vdashmoduleinst \{ \begin{array}[t]{@{}l@{~}l@{}} \MITYPES & \functype^\ast, \\ \MIFUNCS & \funcaddr^\ast, \\ \MITABLES & \tableaddr^\ast, \\ \MIMEMS & \memaddr^\ast, \\ \MIGLOBALS & \globaladdr^\ast, \\ \MIELEMS & \elemaddr^\ast, \\ \MIDATAS & \dataaddr^\ast, \\ \MIEXPORTS & \exportinst^\ast ~\} : \{ \begin{array}[t]{@{}l@{~}l@{}} \CTYPES & \functype^\ast, \\ \CFUNCS & {\functype'}^\ast, \\ \CTABLES & \tabletype^\ast, \\ \CMEMS & \memtype^\ast, \\ \CGLOBALS & \globaltype^\ast ~\} \end{array} \end{array} } .. index:: configuration, administrative instruction, store, frame .. _frame-context: .. _valid-config: Configuration Validity ~~~~~~~~~~~~~~~~~~~~~~ To relate the WebAssembly :ref:`type system ` to its :ref:`execution semantics `, the :ref:`typing rules for instructions ` must be extended to :ref:`configurations ` :math:`S;T`, which relates the :ref:`store ` to execution :ref:`threads `. Configurations and threads are classified by their :ref:`result type `. In addition to the store :math:`S`, threads are typed under a *return type* :math:`\resulttype^?`, which controls whether and with which type a |return| instruction is allowed. This type is absent (:math:`\epsilon`) except for instruction sequences inside an administrative |FRAME| instruction. Finally, :ref:`frames ` are classified with *frame contexts*, which extend the :ref:`module contexts ` of a frame's associated :ref:`module instance ` with the :ref:`locals ` that the frame contains. .. index:: result type, thread :ref:`Configurations ` :math:`S;T` ................................................. * The :ref:`store ` :math:`S` must be :ref:`valid `. * Under no allowed return type, the :ref:`thread ` :math:`T` must be :ref:`valid ` with some :ref:`result type ` :math:`[t^\ast]`. * Then the configuration is valid with the :ref:`result type ` :math:`[t^\ast]`. .. math:: \frac{ \vdashstore S \ok \qquad S; \epsilon \vdashthread T : [t^\ast] }{ \vdashconfig S; T : [t^\ast] } .. index:: thread, frame, instruction, result type, context .. _valid-thread: :ref:`Threads ` :math:`F;\instr^\ast` .................................................... * Let :math:`\resulttype^?` be the current allowed return type. * The :ref:`frame ` :math:`F` must be :ref:`valid ` with a :ref:`context ` :math:`C`. * Let :math:`C'` be the same :ref:`context ` as :math:`C`, but with |CRETURN| set to :math:`\resulttype^?`. * Under context :math:`C'`, the instruction sequence :math:`\instr^\ast` must be :ref:`valid ` with some type :math:`[] \to [t^\ast]`. * Then the thread is valid with the :ref:`result type ` :math:`[t^\ast]`. .. math:: \frac{ S \vdashframe F : C \qquad S; C,\CRETURN~\resulttype^? \vdashinstrseq \instr^\ast : [] \to [t^\ast] }{ S; \resulttype^? \vdashthread F; \instr^\ast : [t^\ast] } .. index:: frame, local, module instance, value, value type, context .. _valid-frame: :ref:`Frames ` :math:`\{\ALOCALS~\val^\ast, \AMODULE~\moduleinst\}` ................................................................................. * The :ref:`module instance ` :math:`\moduleinst` must be :ref:`valid ` with some :ref:`module context ` :math:`C`. * Each :ref:`value ` :math:`\val_i` in :math:`\val^\ast` must be :ref:`valid ` with some :ref:`value type ` :math:`t_i`. * Let :math:`t^\ast` the concatenation of all :math:`t_i` in order. * Let :math:`C'` be the same :ref:`context ` as :math:`C`, but with the :ref:`value types ` :math:`t^\ast` prepended to the |CLOCALS| vector. * Then the frame is valid with :ref:`frame context ` :math:`C'`. .. math:: \frac{ S \vdashmoduleinst \moduleinst : C \qquad (S \vdashval \val : t)^\ast }{ S \vdashframe \{\ALOCALS~\val^\ast, \AMODULE~\moduleinst\} : (C, \CLOCALS~t^\ast) } .. index:: administrative instruction, value type, context, store .. _valid-instr-admin: Administrative Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Typing rules for :ref:`administrative instructions ` are specified as follows. In addition to the :ref:`context ` :math:`C`, typing of these instructions is defined under a given :ref:`store ` :math:`S`. To that end, all previous typing judgements :math:`C \vdash \X{prop}` are generalized to include the store, as in :math:`S; C \vdash \X{prop}`, by implicitly adding :math:`S` to all rules -- :math:`S` is never modified by the pre-existing rules, but it is accessed in the extra rules for :ref:`administrative instructions ` given below. .. index:: trap :math:`\TRAP` ............. * The instruction is valid with type :math:`[t_1^\ast] \to [t_2^\ast]`, for any sequences of :ref:`value types ` :math:`t_1^\ast` and :math:`t_2^\ast`. .. math:: \frac{ }{ S; C \vdashadmininstr \TRAP : [t_1^\ast] \to [t_2^\ast] } .. index:: extern address :math:`\REFEXTERNADDR~\externaddr` .................................. * The instruction is valid with type :math:`[] \to [\EXTERNREF]`. .. math:: \frac{ }{ S; C \vdashadmininstr \REFEXTERNADDR~\externaddr : [] \to [\EXTERNREF] } .. index:: function address, extern value, extern type, function type :math:`\REFFUNCADDR~\funcaddr` .............................. * The :ref:`external function value ` :math:`\EVFUNC~\funcaddr` must be :ref:`valid ` with :ref:`external function type ` :math:`\ETFUNC \functype`. * Then the instruction is valid with type :math:`[] \to [\FUNCREF]`. .. math:: \frac{ S \vdashexternval \EVFUNC~\funcaddr : \ETFUNC~\functype }{ S; C \vdashadmininstr \REFFUNCADDR~\funcaddr : [] \to [\FUNCREF] } .. index:: function address, extern value, extern type, function type :math:`\INVOKE~\funcaddr` ......................... * The :ref:`external function value ` :math:`\EVFUNC~\funcaddr` must be :ref:`valid ` with :ref:`external function type ` :math:`\ETFUNC ([t_1^\ast] \to [t_2^\ast])`. * Then the instruction is valid with type :math:`[t_1^\ast] \to [t_2^\ast]`. .. math:: \frac{ S \vdashexternval \EVFUNC~\funcaddr : \ETFUNC~[t_1^\ast] \to [t_2^\ast] }{ S; C \vdashadmininstr \INVOKE~\funcaddr : [t_1^\ast] \to [t_2^\ast] } .. index:: label, instruction, result type :math:`\LABEL_n\{\instr_0^\ast\}~\instr^\ast~\END` .................................................. * The instruction sequence :math:`\instr_0^\ast` must be :ref:`valid ` with some type :math:`[t_1^n] \to [t_2^*]`. * Let :math:`C'` be the same :ref:`context ` as :math:`C`, but with the :ref:`result type ` :math:`[t_1^n]` prepended to the |CLABELS| vector. * Under context :math:`C'`, the instruction sequence :math:`\instr^\ast` must be :ref:`valid ` with type :math:`[] \to [t_2^*]`. * Then the compound instruction is valid with type :math:`[] \to [t_2^*]`. .. math:: \frac{ S; C \vdashinstrseq \instr_0^\ast : [t_1^n] \to [t_2^*] \qquad S; C,\CLABELS\,[t_1^n] \vdashinstrseq \instr^\ast : [] \to [t_2^*] }{ S; C \vdashadmininstr \LABEL_n\{\instr_0^\ast\}~\instr^\ast~\END : [] \to [t_2^*] } .. index:: frame, instruction, result type :math:`\FRAME_n\{F\}~\instr^\ast~\END` ........................................... * Under the return type :math:`[t^n]`, the :ref:`thread ` :math:`F; \instr^\ast` must be :ref:`valid ` with :ref:`result type ` :math:`[t^n]`. * Then the compound instruction is valid with type :math:`[] \to [t^n]`. .. math:: \frac{ S; [t^n] \vdashinstrseq F; \instr^\ast : [t^n] }{ S; C \vdashadmininstr \FRAME_n\{F\}~\instr^\ast~\END : [] \to [t^n] } .. index:: ! store extension, store .. _extend: Store Extension ~~~~~~~~~~~~~~~ Programs can mutate the :ref:`store ` and its contained instances. Any such modification must respect certain invariants, such as not removing allocated instances or changing immutable definitions. While these invariants are inherent to the execution semantics of WebAssembly :ref:`instructions ` and :ref:`modules `, :ref:`host functions ` do not automatically adhere to them. Consequently, the required invariants must be stated as explicit constraints on the :ref:`invocation ` of host functions. Soundness only holds when the :ref:`embedder ` ensures these constraints. The necessary constraints are codified by the notion of store *extension*: a store state :math:`S'` extends state :math:`S`, written :math:`S \extendsto S'`, when the following rules hold. .. note:: Extension does not imply that the new store is valid, which is defined separately :ref:`above `. .. index:: store, function instance, table instance, memory instance, global instance .. _extend-store: :ref:`Store ` :math:`S` ..................................... * The length of :math:`S.\SFUNCS` must not shrink. * The length of :math:`S.\STABLES` must not shrink. * The length of :math:`S.\SMEMS` must not shrink. * The length of :math:`S.\SGLOBALS` must not shrink. * The length of :math:`S.\SELEMS` must not shrink. * The length of :math:`S.\SDATAS` must not shrink. * For each :ref:`function instance ` :math:`\funcinst_i` in the original :math:`S.\SFUNCS`, the new function instance must be an :ref:`extension ` of the old. * For each :ref:`table instance ` :math:`\tableinst_i` in the original :math:`S.\STABLES`, the new table instance must be an :ref:`extension ` of the old. * For each :ref:`memory instance ` :math:`\meminst_i` in the original :math:`S.\SMEMS`, the new memory instance must be an :ref:`extension ` of the old. * For each :ref:`global instance ` :math:`\globalinst_i` in the original :math:`S.\SGLOBALS`, the new global instance must be an :ref:`extension ` of the old. * For each :ref:`element instance ` :math:`\eleminst_i` in the original :math:`S.\SELEMS`, the new global instance must be an :ref:`extension ` of the old. * For each :ref:`data instance ` :math:`\datainst_i` in the original :math:`S.\SDATAS`, the new global instance must be an :ref:`extension ` of the old. .. math:: \frac{ \begin{array}{@{}ccc@{}} S_1.\SFUNCS = \funcinst_1^\ast & S_2.\SFUNCS = {\funcinst'_1}^\ast~\funcinst_2^\ast & (\vdashfuncinstextends \funcinst_1 \extendsto \funcinst'_1)^\ast \\ S_1.\STABLES = \tableinst_1^\ast & S_2.\STABLES = {\tableinst'_1}^\ast~\tableinst_2^\ast & (\vdashtableinstextends \tableinst_1 \extendsto \tableinst'_1)^\ast \\ S_1.\SMEMS = \meminst_1^\ast & S_2.\SMEMS = {\meminst'_1}^\ast~\meminst_2^\ast & (\vdashmeminstextends \meminst_1 \extendsto \meminst'_1)^\ast \\ S_1.\SGLOBALS = \globalinst_1^\ast & S_2.\SGLOBALS = {\globalinst'_1}^\ast~\globalinst_2^\ast & (\vdashglobalinstextends \globalinst_1 \extendsto \globalinst'_1)^\ast \\ S_1.\SELEMS = \eleminst_1^\ast & S_2.\SELEMS = {\eleminst'_1}^\ast~\eleminst_2^\ast & (\vdasheleminstextends \eleminst_1 \extendsto \eleminst'_1)^\ast \\ S_1.\SDATAS = \datainst_1^\ast & S_2.\SDATAS = {\datainst'_1}^\ast~\datainst_2^\ast & (\vdashdatainstextends \datainst_1 \extendsto \datainst'_1)^\ast \\ \end{array} }{ \vdashstoreextends S_1 \extendsto S_2 } .. index:: function instance .. _extend-funcinst: :ref:`Function Instance ` :math:`\funcinst` ............................................................ * A function instance must remain unchanged. .. math:: \frac{ }{ \vdashfuncinstextends \funcinst \extendsto \funcinst } .. index:: table instance .. _extend-tableinst: :ref:`Table Instance ` :math:`\tableinst` ........................................................... * The :ref:`table type ` :math:`\tableinst.\TITYPE` must remain unchanged. * The length of :math:`\tableinst.\TIELEM` must not shrink. .. math:: \frac{ n_1 \leq n_2 }{ \vdashtableinstextends \{\TITYPE~\X{tt}, \TIELEM~(\X{fa}_1^?)^{n_1}\} \extendsto \{\TITYPE~\X{tt}, \TIELEM~(\X{fa}_2^?)^{n_2}\} } .. index:: memory instance .. _extend-meminst: :ref:`Memory Instance ` :math:`\meminst` ........................................................ * The :ref:`memory type ` :math:`\meminst.\MITYPE` must remain unchanged. * The length of :math:`\meminst.\MIDATA` must not shrink. .. math:: \frac{ n_1 \leq n_2 }{ \vdashmeminstextends \{\MITYPE~\X{mt}, \MIDATA~b_1^{n_1}\} \extendsto \{\MITYPE~\X{mt}, \MIDATA~b_2^{n_2}\} } .. index:: global instance, value, mutability .. _extend-globalinst: :ref:`Global Instance ` :math:`\globalinst` .............................................................. * The :ref:`global type ` :math:`\globalinst.\GITYPE` must remain unchanged. * Let :math:`\mut~t` be the structure of :math:`\globalinst.\GITYPE`. * If :math:`\mut` is |MCONST|, then the :ref:`value ` :math:`\globalinst.\GIVALUE` must remain unchanged. .. math:: \frac{ \mut = \MVAR \vee \val_1 = \val_2 }{ \vdashglobalinstextends \{\GITYPE~(\mut~t), \GIVALUE~\val_1\} \extendsto \{\GITYPE~(\mut~t), \GIVALUE~\val_2\} } .. index:: element instance .. _extend-eleminst: :ref:`Element Instance ` :math:`\eleminst` ........................................................... * The vector :math:`\eleminst.\EIELEM` must either remain unchanged or shrink to length :math:`0`. .. math:: \frac{ \X{fa}_1^\ast = \X{fa}_2^\ast \vee \X{fa}_2^\ast = \epsilon }{ \vdasheleminstextends \{\EIELEM~\X{fa}_1^\ast\} \extendsto \{\EIELEM~\X{fa}_2^\ast\} } .. index:: data instance .. _extend-datainst: :ref:`Data Instance ` :math:`\datainst` ........................................................ * The vector :math:`\datainst.\DIDATA` must either remain unchanged or shrink to length :math:`0`. .. math:: \frac{ b_1^\ast = b_2^\ast \vee b_2^\ast = \epsilon }{ \vdashdatainstextends \{\DIDATA~b_1^\ast\} \extendsto \{\DIDATA~b_2^\ast\} } .. index:: ! preservation, ! progress, soundness, configuration, thread, terminal configuration, instantiation, invocation, validity, module .. _soundness-statement: Theorems ~~~~~~~~ Given the definition of :ref:`valid configurations `, the standard soundness theorems hold. [#cite-cpp2018]_ **Theorem (Preservation).** If a :ref:`configuration ` :math:`S;T` is :ref:`valid ` with :ref:`result type ` :math:`[t^\ast]` (i.e., :math:`\vdashconfig S;T : [t^\ast]`), and steps to :math:`S';T'` (i.e., :math:`S;T \stepto S';T'`), then :math:`S';T'` is a valid configuration with the same result type (i.e., :math:`\vdashconfig S';T' : [t^\ast]`). Furthermore, :math:`S'` is an :ref:`extension ` of :math:`S` (i.e., :math:`\vdashstoreextends S \extendsto S'`). A *terminal* :ref:`thread ` is one whose sequence of :ref:`instructions ` is a :ref:`result `. A terminal configuration is a configuration whose thread is terminal. **Theorem (Progress).** If a :ref:`configuration ` :math:`S;T` is :ref:`valid ` (i.e., :math:`\vdashconfig S;T : [t^\ast]` for some :ref:`result type ` :math:`[t^\ast]`), then either it is terminal, or it can step to some configuration :math:`S';T'` (i.e., :math:`S;T \stepto S';T'`). From Preservation and Progress the soundness of the WebAssembly type system follows directly. **Corollary (Soundness).** If a :ref:`configuration ` :math:`S;T` is :ref:`valid ` (i.e., :math:`\vdashconfig S;T : [t^\ast]` for some :ref:`result type ` :math:`[t^\ast]`), then it either diverges or takes a finite number of steps to reach a terminal configuration :math:`S';T'` (i.e., :math:`S;T \stepto^\ast S';T'`) that is valid with the same result type (i.e., :math:`\vdashconfig S';T' : [t^\ast]`) and where :math:`S'` is an :ref:`extension ` of :math:`S` (i.e., :math:`\vdashstoreextends S \extendsto S'`). In other words, every thread in a valid configuration either runs forever, traps, or terminates with a result that has the expected type. Consequently, given a :ref:`valid store `, no computation defined by :ref:`instantiation ` or :ref:`invocation ` of a valid module can "crash" or otherwise (mis)behave in ways not covered by the :ref:`execution ` semantics given in this specification. .. [#cite-pldi2017] The formalization and theorems are derived from the following article: Andreas Haas, Andreas Rossberg, Derek Schuff, Ben Titzer, Dan Gohman, Luke Wagner, Alon Zakai, JF Bastien, Michael Holman. |PLDI2017|_. Proceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI 2017). ACM 2017. .. [#cite-cpp2018] A machine-verified version of the formalization and soundness proof is described in the following article: Conrad Watt. |CPP2018|_. Proceedings of the 7th ACM SIGPLAN Conference on Certified Programs and Proofs (CPP 2018). ACM 2018. ================================================ FILE: document/core/binary/conventions.rst ================================================ .. index:: ! binary format, module, byte, file extension, abstract syntax Conventions ----------- The binary format for WebAssembly :ref:`modules ` is a dense linear *encoding* of their :ref:`abstract syntax `. [#compression]_ The format is defined by an *attribute grammar* whose only terminal symbols are :ref:`bytes `. A byte sequence is a well-formed encoding of a module if and only if it is generated by the grammar. Each production of this grammar has exactly one synthesized attribute: the abstract syntax that the respective byte sequence encodes. Thus, the attribute grammar implicitly defines a *decoding* function (i.e., a parsing function for the binary format). Except for a few exceptions, the binary grammar closely mirrors the grammar of the abstract syntax. .. note:: Some phrases of abstract syntax have multiple possible encodings in the binary format. For example, numbers may be encoded as if they had optional leading zeros. Implementations of decoders must support all possible alternatives; implementations of encoders can pick any allowed encoding. The recommended extension for files containing WebAssembly modules in binary format is ":math:`\T{.wasm}`" and the recommended |MediaType|_ is ":math:`\T{application/wasm}`". .. [#compression] Additional encoding layers -- for example, introducing compression -- may be defined on top of the basic representation defined here. However, such layers are outside the scope of the current specification. .. index:: grammar notation, notation, byte single: binary format; grammar pair: binary format; notation .. _binary-grammar: Grammar ~~~~~~~ The following conventions are adopted in defining grammar rules for the binary format. They mirror the conventions used for :ref:`abstract syntax `. In order to distinguish symbols of the binary syntax from symbols of the abstract syntax, :math:`\mathtt{typewriter}` font is adopted for the former. * Terminal symbols are :ref:`bytes ` expressed in hexadecimal notation: :math:`\hex{0F}`. * Nonterminal symbols are written in typewriter font: :math:`\B{valtype}, \B{instr}`. * :math:`B^n` is a sequence of :math:`n\geq 0` iterations of :math:`B`. * :math:`B^\ast` is a possibly empty sequence of iterations of :math:`B`. (This is a shorthand for :math:`B^n` used where :math:`n` is not relevant.) * :math:`B^?` is an optional occurrence of :math:`B`. (This is a shorthand for :math:`B^n` where :math:`n \leq 1`.) * :math:`x{:}B` denotes the same language as the nonterminal :math:`B`, but also binds the variable :math:`x` to the attribute synthesized for :math:`B`. * Productions are written :math:`\B{sym} ::= B_1 \Rightarrow A_1 ~|~ \dots ~|~ B_n \Rightarrow A_n`, where each :math:`A_i` is the attribute that is synthesized for :math:`\B{sym}` in the given case, usually from attribute variables bound in :math:`B_i`. * Some productions are augmented by side conditions in parentheses, which restrict the applicability of the production. They provide a shorthand for a combinatorial expansion of the production into many separate cases. * If the same meta variable or non-terminal symbol appears multiple times in a production (in the syntax or in an attribute), then all those occurrences must have the same instantiation. (This is a shorthand for a side condition requiring multiple different variables to be equal.) .. note:: For example, the :ref:`binary grammar ` for :ref:`value types ` is given as follows: .. math:: \begin{array}{llcll@{\qquad\qquad}l} \production{value types} & \Bvaltype &::=& \hex{7F} &\Rightarrow& \I32 \\ &&|& \hex{7E} &\Rightarrow& \I64 \\ &&|& \hex{7D} &\Rightarrow& \F32 \\ &&|& \hex{7C} &\Rightarrow& \F64 \\ \end{array} Consequently, the byte :math:`\hex{7F}` encodes the type |I32|, :math:`\hex{7E}` encodes the type |I64|, and so forth. No other byte value is allowed as the encoding of a value type. The :ref:`binary grammar ` for :ref:`limits ` is defined as follows: .. math:: \begin{array}{llclll} \production{limits} & \Blimits &::=& \hex{00}~~n{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~\epsilon \} \\ &&|& \hex{01}~~n{:}\Bu32~~m{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~m \} \\ \end{array} That is, a limits pair is encoded as either the byte :math:`\hex{00}` followed by the encoding of a |U32| value, or the byte :math:`\hex{01}` followed by two such encodings. The variables :math:`n` and :math:`m` name the attributes of the respective |Bu32| nonterminals, which in this case are the actual :ref:`unsigned integers ` those decode into. The attribute of the complete production then is the abstract syntax for the limit, expressed in terms of the former values. .. _binary-notation: Auxiliary Notation ~~~~~~~~~~~~~~~~~~ When dealing with binary encodings the following notation is also used: * :math:`\epsilon` denotes the empty byte sequence. * :math:`||B||` is the length of the byte sequence generated from the production :math:`B` in a derivation. .. index:: vector pair: binary format; vector .. _binary-vec: Vectors ~~~~~~~ :ref:`Vectors ` are encoded with their |Bu32| length followed by the encoding of their element sequence. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{vector} & \Bvec(\B{B}) &::=& n{:}\Bu32~~(x{:}\B{B})^n &\Rightarrow& x^n \\ \end{array} ================================================ FILE: document/core/binary/index.rst ================================================ .. _binary: Binary Format ============= .. toctree:: :maxdepth: 2 conventions values types instructions modules ================================================ FILE: document/core/binary/instructions.rst ================================================ .. index:: instruction, ! opcode .. _binary-instr: Instructions ------------ :ref:`Instructions ` are encoded by *opcodes*. Each opcode is represented by a single byte, and is followed by the instruction's immediate arguments, where present. The only exception are :ref:`structured control instructions `, which consist of several opcodes bracketing their nested instruction sequences. .. note:: Gaps in the byte code ranges for encoding instructions are reserved for future extensions. .. index:: control instructions, structured control, label, block, branch, result type, value type, block type, label index, function index, type index, vector, polymorphism, LEB128 pair: binary format; instruction pair: binary format; block type .. _binary-instr-control: Control Instructions ~~~~~~~~~~~~~~~~~~~~ :ref:`Control instructions ` have varying encodings. For structured instructions, the instruction sequences forming nested blocks are terminated with explicit opcodes for |END| and |ELSE|. :ref:`Block types ` are encoded in special compressed form, by either the byte :math:`\hex{40}` indicating the empty type, as a single :ref:`value type `, or as a :ref:`type index ` encoded as a positive :ref:`signed integer `. .. _binary-blocktype: .. _binary-nop: .. _binary-unreachable: .. _binary-block: .. _binary-loop: .. _binary-if: .. _binary-br: .. _binary-br_if: .. _binary-br_table: .. _binary-return: .. _binary-call: .. _binary-call_indirect: .. math:: \begin{array}{llcllll} \production{block type} & \Bblocktype &::=& \hex{40} &\Rightarrow& \epsilon \\ &&|& t{:}\Bvaltype &\Rightarrow& t \\ &&|& x{:}\Bs33 &\Rightarrow& x & (\iff x \geq 0) \\ \production{instruction} & \Binstr &::=& \hex{00} &\Rightarrow& \UNREACHABLE \\ &&|& \hex{01} &\Rightarrow& \NOP \\ &&|& \hex{02}~~\X{bt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \BLOCK~\X{bt}~\X{in}^\ast~\END \\ &&|& \hex{03}~~\X{bt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \LOOP~\X{bt}~\X{in}^\ast~\END \\ &&|& \hex{04}~~\X{bt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \IF~\X{bt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& \hex{04}~~\X{bt}{:}\Bblocktype~~(\X{in}_1{:}\Binstr)^\ast~~ \hex{05}~~(\X{in}_2{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \IF~\X{bt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ &&|& \hex{0C}~~l{:}\Blabelidx &\Rightarrow& \BR~l \\ &&|& \hex{0D}~~l{:}\Blabelidx &\Rightarrow& \BRIF~l \\ &&|& \hex{0E}~~l^\ast{:}\Bvec(\Blabelidx)~~l_N{:}\Blabelidx &\Rightarrow& \BRTABLE~l^\ast~l_N \\ &&|& \hex{0F} &\Rightarrow& \RETURN \\ &&|& \hex{10}~~x{:}\Bfuncidx &\Rightarrow& \CALL~x \\ &&|& \hex{11}~~y{:}\Btypeidx~~x{:}\Btableidx &\Rightarrow& \CALLINDIRECT~x~y \\ \end{array} .. note:: The |ELSE| opcode :math:`\hex{05}` in the encoding of an |IF| instruction can be omitted if the following instruction sequence is empty. Unlike any :ref:`other occurrence `, the :ref:`type index ` in a :ref:`block type ` is encoded as a positive :ref:`signed integer `, so that its |SignedLEB128| bit pattern cannot collide with the encoding of :ref:`value types ` or the special code :math:`\hex{40}`, which correspond to the LEB128 encoding of negative integers. To avoid any loss in the range of allowed indices, it is treated as a 33 bit signed integer. In future versions of WebAssembly, the zero byte occurring in the encoding of the |CALLINDIRECT| instruction may be used to index additional tables. .. index:: reference instruction pair: binary format; instruction .. _binary-instr-ref: Reference Instructions ~~~~~~~~~~~~~~~~~~~~~~ :ref:`Reference instructions ` are represented by single byte codes. .. _binary-ref.null: .. _binary-ref.isnull: .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{D0}~~t{:}\Breftype &\Rightarrow& \REFNULL~t \\ &&|& \hex{D1} &\Rightarrow& \REFISNULL \\ &&|& \hex{D2}~~x{:}\Bfuncidx &\Rightarrow& \REFFUNC~x \\ \end{array} .. note:: These opcode assignments are preliminary. .. index:: parametric instruction, value type, polymorphism pair: binary format; instruction .. _binary-instr-parametric: Parametric Instructions ~~~~~~~~~~~~~~~~~~~~~~~ :ref:`Parametric instructions ` are represented by single byte codes, possibly followed by a type annotation. .. _binary-drop: .. _binary-select: .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{1A} &\Rightarrow& \DROP \\ &&|& \hex{1B} &\Rightarrow& \SELECT \\ &&|& \hex{1C}~~t^\ast{:}\Bvec(\Bvaltype) &\Rightarrow& \SELECT~t^\ast \\ \end{array} .. index:: variable instructions, local index, global index pair: binary format; instruction .. _binary-instr-variable: Variable Instructions ~~~~~~~~~~~~~~~~~~~~~ :ref:`Variable instructions ` are represented by byte codes followed by the encoding of the respective :ref:`index `. .. _binary-local.get: .. _binary-local.set: .. _binary-local.tee: .. _binary-global.get: .. _binary-global.set: .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{20}~~x{:}\Blocalidx &\Rightarrow& \LOCALGET~x \\ &&|& \hex{21}~~x{:}\Blocalidx &\Rightarrow& \LOCALSET~x \\ &&|& \hex{22}~~x{:}\Blocalidx &\Rightarrow& \LOCALTEE~x \\ &&|& \hex{23}~~x{:}\Bglobalidx &\Rightarrow& \GLOBALGET~x \\ &&|& \hex{24}~~x{:}\Bglobalidx &\Rightarrow& \GLOBALSET~x \\ \end{array} .. index:: table instruction, table index pair: binary format; instruction .. _binary-instr-table: .. _binary-table.get: .. _binary-table.set: .. _binary-table.size: .. _binary-table.grow: .. _binary-table.fill: .. _binary-table.copy: .. _binary-table.init: .. _binary-elem.drop: Table Instructions ~~~~~~~~~~~~~~~~~~ :ref:`Table instructions ` are represented by either single byte or two byte codes. .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{25}~~x{:}\Btableidx &\Rightarrow& \TABLEGET~x \\ &&|& \hex{26}~~x{:}\Btableidx &\Rightarrow& \TABLESET~x \\ &&|& \hex{FC}~~12{:}\Bu32~~y{:}\Belemidx~~x{:}\Btableidx &\Rightarrow& \TABLEINIT~x~y \\ &&|& \hex{FC}~~13{:}\Bu32~~x{:}\Belemidx &\Rightarrow& \ELEMDROP~x \\ &&|& \hex{FC}~~14{:}\Bu32~~x{:}\Btableidx~~y{:}\Btableidx &\Rightarrow& \TABLECOPY~x~y \\ &&|& \hex{FC}~~15{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLEGROW~x \\ &&|& \hex{FC}~~16{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLESIZE~x \\ &&|& \hex{FC}~~17{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLEFILL~x \\ \end{array} .. index:: memory instruction, memory index pair: binary format; instruction .. _binary-instr-memory: Memory Instructions ~~~~~~~~~~~~~~~~~~~ Each variant of :ref:`memory instruction ` is encoded with a different byte code. Loads and stores are followed by the encoding of their |memarg| immediate. .. _binary-memarg: .. _binary-load: .. _binary-loadn: .. _binary-store: .. _binary-storen: .. _binary-memory.size: .. _binary-memory.grow: .. _binary-memory.fill: .. _binary-memory.copy: .. _binary-memory.init: .. _binary-data.drop: .. math:: \begin{array}{llclll} \production{memory argument} & \Bmemarg &::=& a{:}\Bu32~~o{:}\Bu32 &\Rightarrow& \{ \ALIGN~a,~\OFFSET~o \} \\ \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{28}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD~m \\ &&|& \hex{29}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD~m \\ &&|& \hex{2A}~~m{:}\Bmemarg &\Rightarrow& \F32.\LOAD~m \\ &&|& \hex{2B}~~m{:}\Bmemarg &\Rightarrow& \F64.\LOAD~m \\ &&|& \hex{2C}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{8\_s}~m \\ &&|& \hex{2D}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{8\_u}~m \\ &&|& \hex{2E}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{16\_s}~m \\ &&|& \hex{2F}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{16\_u}~m \\ &&|& \hex{30}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{8\_s}~m \\ &&|& \hex{31}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{8\_u}~m \\ &&|& \hex{32}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{16\_s}~m \\ &&|& \hex{33}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{16\_u}~m \\ &&|& \hex{34}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{32\_s}~m \\ &&|& \hex{35}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{32\_u}~m \\ &&|& \hex{36}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE~m \\ &&|& \hex{37}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE~m \\ &&|& \hex{38}~~m{:}\Bmemarg &\Rightarrow& \F32.\STORE~m \\ &&|& \hex{39}~~m{:}\Bmemarg &\Rightarrow& \F64.\STORE~m \\ &&|& \hex{3A}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE\K{8}~m \\ &&|& \hex{3B}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE\K{16}~m \\ &&|& \hex{3C}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{8}~m \\ &&|& \hex{3D}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{16}~m \\ &&|& \hex{3E}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{32}~m \\ &&|& \hex{3F}~~\hex{00} &\Rightarrow& \MEMORYSIZE \\ &&|& \hex{40}~~\hex{00} &\Rightarrow& \MEMORYGROW \\ &&|& \hex{FC}~~8{:}\Bu32~~x{:}\Bdataidx~\hex{00} &\Rightarrow& \MEMORYINIT~x \\ &&|& \hex{FC}~~9{:}\Bu32~~x{:}\Bdataidx &\Rightarrow& \DATADROP~x \\ &&|& \hex{FC}~~10{:}\Bu32~~\hex{00}~~\hex{00} &\Rightarrow& \MEMORYCOPY \\ &&|& \hex{FC}~~11{:}\Bu32~~\hex{00} &\Rightarrow& \MEMORYFILL \\ \end{array} .. note:: In future versions of WebAssembly, the additional zero bytes occurring in the encoding of the |MEMORYSIZE|, |MEMORYGROW|, |MEMORYCOPY|, and |MEMORYFILL| instructions may be used to index additional memories. .. index:: numeric instruction pair: binary format; instruction .. _binary-instr-numeric: Numeric Instructions ~~~~~~~~~~~~~~~~~~~~ All variants of :ref:`numeric instructions ` are represented by separate byte codes. The |CONST| instructions are followed by the respective literal. .. _binary-const: .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots \\&&|& \hex{41}~~n{:}\Bi32 &\Rightarrow& \I32.\CONST~n \\ &&|& \hex{42}~~n{:}\Bi64 &\Rightarrow& \I64.\CONST~n \\ &&|& \hex{43}~~z{:}\Bf32 &\Rightarrow& \F32.\CONST~z \\ &&|& \hex{44}~~z{:}\Bf64 &\Rightarrow& \F64.\CONST~z \\ \end{array} All other numeric instructions are plain opcodes without any immediates. .. _binary-testop: .. _binary-relop: .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots && \phantom{thisshouldbeenough} \\&&|& \hex{45} &\Rightarrow& \I32.\EQZ \\ &&|& \hex{46} &\Rightarrow& \I32.\EQ \\ &&|& \hex{47} &\Rightarrow& \I32.\NE \\ &&|& \hex{48} &\Rightarrow& \I32.\LT\K{\_s} \\ &&|& \hex{49} &\Rightarrow& \I32.\LT\K{\_u} \\ &&|& \hex{4A} &\Rightarrow& \I32.\GT\K{\_s} \\ &&|& \hex{4B} &\Rightarrow& \I32.\GT\K{\_u} \\ &&|& \hex{4C} &\Rightarrow& \I32.\LE\K{\_s} \\ &&|& \hex{4D} &\Rightarrow& \I32.\LE\K{\_u} \\ &&|& \hex{4E} &\Rightarrow& \I32.\GE\K{\_s} \\ &&|& \hex{4F} &\Rightarrow& \I32.\GE\K{\_u} \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{50} &\Rightarrow& \I64.\EQZ \\ &&|& \hex{51} &\Rightarrow& \I64.\EQ \\ &&|& \hex{52} &\Rightarrow& \I64.\NE \\ &&|& \hex{53} &\Rightarrow& \I64.\LT\K{\_s} \\ &&|& \hex{54} &\Rightarrow& \I64.\LT\K{\_u} \\ &&|& \hex{55} &\Rightarrow& \I64.\GT\K{\_s} \\ &&|& \hex{56} &\Rightarrow& \I64.\GT\K{\_u} \\ &&|& \hex{57} &\Rightarrow& \I64.\LE\K{\_s} \\ &&|& \hex{58} &\Rightarrow& \I64.\LE\K{\_u} \\ &&|& \hex{59} &\Rightarrow& \I64.\GE\K{\_s} \\ &&|& \hex{5A} &\Rightarrow& \I64.\GE\K{\_u} \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{5B} &\Rightarrow& \F32.\EQ \\ &&|& \hex{5C} &\Rightarrow& \F32.\NE \\ &&|& \hex{5D} &\Rightarrow& \F32.\LT \\ &&|& \hex{5E} &\Rightarrow& \F32.\GT \\ &&|& \hex{5F} &\Rightarrow& \F32.\LE \\ &&|& \hex{60} &\Rightarrow& \F32.\GE \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{61} &\Rightarrow& \F64.\EQ \\ &&|& \hex{62} &\Rightarrow& \F64.\NE \\ &&|& \hex{63} &\Rightarrow& \F64.\LT \\ &&|& \hex{64} &\Rightarrow& \F64.\GT \\ &&|& \hex{65} &\Rightarrow& \F64.\LE \\ &&|& \hex{66} &\Rightarrow& \F64.\GE \\ \end{array} .. _binary-unop: .. _binary-binop: .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{67} &\Rightarrow& \I32.\CLZ \\ &&|& \hex{68} &\Rightarrow& \I32.\CTZ \\ &&|& \hex{69} &\Rightarrow& \I32.\POPCNT \\ &&|& \hex{6A} &\Rightarrow& \I32.\ADD \\ &&|& \hex{6B} &\Rightarrow& \I32.\SUB \\ &&|& \hex{6C} &\Rightarrow& \I32.\MUL \\ &&|& \hex{6D} &\Rightarrow& \I32.\DIV\K{\_s} \\ &&|& \hex{6E} &\Rightarrow& \I32.\DIV\K{\_u} \\ &&|& \hex{6F} &\Rightarrow& \I32.\REM\K{\_s} \\ &&|& \hex{70} &\Rightarrow& \I32.\REM\K{\_u} \\ &&|& \hex{71} &\Rightarrow& \I32.\AND \\ &&|& \hex{72} &\Rightarrow& \I32.\OR \\ &&|& \hex{73} &\Rightarrow& \I32.\XOR \\ &&|& \hex{74} &\Rightarrow& \I32.\SHL \\ &&|& \hex{75} &\Rightarrow& \I32.\SHR\K{\_s} \\ &&|& \hex{76} &\Rightarrow& \I32.\SHR\K{\_u} \\ &&|& \hex{77} &\Rightarrow& \I32.\ROTL \\ &&|& \hex{78} &\Rightarrow& \I32.\ROTR \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{79} &\Rightarrow& \I64.\CLZ \\ &&|& \hex{7A} &\Rightarrow& \I64.\CTZ \\ &&|& \hex{7B} &\Rightarrow& \I64.\POPCNT \\ &&|& \hex{7C} &\Rightarrow& \I64.\ADD \\ &&|& \hex{7D} &\Rightarrow& \I64.\SUB \\ &&|& \hex{7E} &\Rightarrow& \I64.\MUL \\ &&|& \hex{7F} &\Rightarrow& \I64.\DIV\K{\_s} \\ &&|& \hex{80} &\Rightarrow& \I64.\DIV\K{\_u} \\ &&|& \hex{81} &\Rightarrow& \I64.\REM\K{\_s} \\ &&|& \hex{82} &\Rightarrow& \I64.\REM\K{\_u} \\ &&|& \hex{83} &\Rightarrow& \I64.\AND \\ &&|& \hex{84} &\Rightarrow& \I64.\OR \\ &&|& \hex{85} &\Rightarrow& \I64.\XOR \\ &&|& \hex{86} &\Rightarrow& \I64.\SHL \\ &&|& \hex{87} &\Rightarrow& \I64.\SHR\K{\_s} \\ &&|& \hex{88} &\Rightarrow& \I64.\SHR\K{\_u} \\ &&|& \hex{89} &\Rightarrow& \I64.\ROTL \\ &&|& \hex{8A} &\Rightarrow& \I64.\ROTR \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{8B} &\Rightarrow& \F32.\ABS \\ &&|& \hex{8C} &\Rightarrow& \F32.\NEG \\ &&|& \hex{8D} &\Rightarrow& \F32.\CEIL \\ &&|& \hex{8E} &\Rightarrow& \F32.\FLOOR \\ &&|& \hex{8F} &\Rightarrow& \F32.\TRUNC \\ &&|& \hex{90} &\Rightarrow& \F32.\NEAREST \\ &&|& \hex{91} &\Rightarrow& \F32.\SQRT \\ &&|& \hex{92} &\Rightarrow& \F32.\ADD \\ &&|& \hex{93} &\Rightarrow& \F32.\SUB \\ &&|& \hex{94} &\Rightarrow& \F32.\MUL \\ &&|& \hex{95} &\Rightarrow& \F32.\DIV \\ &&|& \hex{96} &\Rightarrow& \F32.\FMIN \\ &&|& \hex{97} &\Rightarrow& \F32.\FMAX \\ &&|& \hex{98} &\Rightarrow& \F32.\COPYSIGN \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{99} &\Rightarrow& \F64.\ABS \\ &&|& \hex{9A} &\Rightarrow& \F64.\NEG \\ &&|& \hex{9B} &\Rightarrow& \F64.\CEIL \\ &&|& \hex{9C} &\Rightarrow& \F64.\FLOOR \\ &&|& \hex{9D} &\Rightarrow& \F64.\TRUNC \\ &&|& \hex{9E} &\Rightarrow& \F64.\NEAREST \\ &&|& \hex{9F} &\Rightarrow& \F64.\SQRT \\ &&|& \hex{A0} &\Rightarrow& \F64.\ADD \\ &&|& \hex{A1} &\Rightarrow& \F64.\SUB \\ &&|& \hex{A2} &\Rightarrow& \F64.\MUL \\ &&|& \hex{A3} &\Rightarrow& \F64.\DIV \\ &&|& \hex{A4} &\Rightarrow& \F64.\FMIN \\ &&|& \hex{A5} &\Rightarrow& \F64.\FMAX \\ &&|& \hex{A6} &\Rightarrow& \F64.\COPYSIGN \\ \end{array} .. _binary-cvtop: .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{A7} &\Rightarrow& \I32.\WRAP\K{\_}\I64 \\ &&|& \hex{A8} &\Rightarrow& \I32.\TRUNC\K{\_}\F32\K{\_s} \\ &&|& \hex{A9} &\Rightarrow& \I32.\TRUNC\K{\_}\F32\K{\_u} \\ &&|& \hex{AA} &\Rightarrow& \I32.\TRUNC\K{\_}\F64\K{\_s} \\ &&|& \hex{AB} &\Rightarrow& \I32.\TRUNC\K{\_}\F64\K{\_u} \\ &&|& \hex{AC} &\Rightarrow& \I64.\EXTEND\K{\_}\I32\K{\_s} \\ &&|& \hex{AD} &\Rightarrow& \I64.\EXTEND\K{\_}\I32\K{\_u} \\ &&|& \hex{AE} &\Rightarrow& \I64.\TRUNC\K{\_}\F32\K{\_s} \\ &&|& \hex{AF} &\Rightarrow& \I64.\TRUNC\K{\_}\F32\K{\_u} \\ &&|& \hex{B0} &\Rightarrow& \I64.\TRUNC\K{\_}\F64\K{\_s} \\ &&|& \hex{B1} &\Rightarrow& \I64.\TRUNC\K{\_}\F64\K{\_u} \\ &&|& \hex{B2} &\Rightarrow& \F32.\CONVERT\K{\_}\I32\K{\_s} \\ &&|& \hex{B3} &\Rightarrow& \F32.\CONVERT\K{\_}\I32\K{\_u} \\ &&|& \hex{B4} &\Rightarrow& \F32.\CONVERT\K{\_}\I64\K{\_s} \\ &&|& \hex{B5} &\Rightarrow& \F32.\CONVERT\K{\_}\I64\K{\_u} \\ &&|& \hex{B6} &\Rightarrow& \F32.\DEMOTE\K{\_}\F64 \\ &&|& \hex{B7} &\Rightarrow& \F64.\CONVERT\K{\_}\I32\K{\_s} \\ &&|& \hex{B8} &\Rightarrow& \F64.\CONVERT\K{\_}\I32\K{\_u} \\ &&|& \hex{B9} &\Rightarrow& \F64.\CONVERT\K{\_}\I64\K{\_s} \\ &&|& \hex{BA} &\Rightarrow& \F64.\CONVERT\K{\_}\I64\K{\_u} \\ &&|& \hex{BB} &\Rightarrow& \F64.\PROMOTE\K{\_}\F32 \\ &&|& \hex{BC} &\Rightarrow& \I32.\REINTERPRET\K{\_}\F32 \\ &&|& \hex{BD} &\Rightarrow& \I64.\REINTERPRET\K{\_}\F64 \\ &&|& \hex{BE} &\Rightarrow& \F32.\REINTERPRET\K{\_}\I32 \\ &&|& \hex{BF} &\Rightarrow& \F64.\REINTERPRET\K{\_}\I64 \\ \end{array} .. math:: \begin{array}{llclll} \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{C0} &\Rightarrow& \I32.\EXTEND\K{8\_s} \\ &&|& \hex{C1} &\Rightarrow& \I32.\EXTEND\K{16\_s} \\ &&|& \hex{C2} &\Rightarrow& \I64.\EXTEND\K{8\_s} \\ &&|& \hex{C3} &\Rightarrow& \I64.\EXTEND\K{16\_s} \\ &&|& \hex{C4} &\Rightarrow& \I64.\EXTEND\K{32\_s} \\ \end{array} .. _binary-cvtop-trunc-sat: The saturating truncation instructions all have a one byte prefix, whereas the actual opcode is encoded by a variable-length :ref:`unsigned integer `. .. math:: \begin{array}{llclll} \production{instruction} & \Binstr &::=& \dots && \phantom{thisshouldbeenough} \\&&|& \hex{FC}~~0{:}\Bu32 &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& \hex{FC}~~1{:}\Bu32 &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& \hex{FC}~~2{:}\Bu32 &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& \hex{FC}~~3{:}\Bu32 &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ &&|& \hex{FC}~~4{:}\Bu32 &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& \hex{FC}~~5{:}\Bu32 &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& \hex{FC}~~6{:}\Bu32 &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& \hex{FC}~~7{:}\Bu32 &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ \end{array} .. index:: expression pair: binary format; expression single: expression; constant .. _binary-expr: Expressions ~~~~~~~~~~~ :ref:`Expressions ` are encoded by their instruction sequence terminated with an explicit :math:`\hex{0B}` opcode for |END|. .. math:: \begin{array}{llclll} \production{expression} & \Bexpr &::=& (\X{in}{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \X{in}^\ast~\END \\ \end{array} ================================================ FILE: document/core/binary/modules.rst ================================================ Modules ------- The binary encoding of modules is organized into *sections*. Most sections correspond to one component of a :ref:`module ` record, except that :ref:`function definitions ` are split into two sections, separating their type declarations in the :ref:`function section ` from their bodies in the :ref:`code section `. .. note:: This separation enables *parallel* and *streaming* compilation of the functions in a module. .. index:: index, type index, function index, table index, memory index, global index, element index, data index, local index, label index pair: binary format; type index pair: binary format; function index pair: binary format; table index pair: binary format; memory index pair: binary format; global index pair: binary format; element index pair: binary format; data index pair: binary format; local index pair: binary format; label index .. _binary-typeidx: .. _binary-funcidx: .. _binary-tableidx: .. _binary-memidx: .. _binary-globalidx: .. _binary-elemidx: .. _binary-dataidx: .. _binary-localidx: .. _binary-labelidx: .. _binary-index: Indices ~~~~~~~ All :ref:`indices ` are encoded with their respective value. .. math:: \begin{array}{llclll} \production{type index} & \Btypeidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{function index} & \Bfuncidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{table index} & \Btableidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{memory index} & \Bmemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{global index} & \Bglobalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{element index} & \Belemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{data index} & \Bdataidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{local index} & \Blocalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ \production{label index} & \Blabelidx &::=& l{:}\Bu32 &\Rightarrow& l \\ \end{array} .. index:: ! section pair: binary format; section .. _binary-section: Sections ~~~~~~~~ Each section consists of * a one-byte section *id*, * the |U32| *size* of the contents, in bytes, * the actual *contents*, whose structure is depended on the section id. Every section is optional; an omitted section is equivalent to the section being present with empty contents. The following parameterized grammar rule defines the generic structure of a section with id :math:`N` and contents described by the grammar :math:`\B{B}`. .. math:: \begin{array}{llclll@{\qquad}l} \production{section} & \Bsection_N(\B{B}) &::=& N{:}\Bbyte~~\X{size}{:}\Bu32~~\X{cont}{:}\B{B} &\Rightarrow& \X{cont} & (\iff \X{size} = ||\B{B}||) \\ &&|& \epsilon &\Rightarrow& \epsilon \end{array} For most sections, the contents :math:`\B{B}` encodes a :ref:`vector `. In these cases, the empty result :math:`\epsilon` is interpreted as the empty vector. .. note:: Other than for unknown :ref:`custom sections `, the :math:`\X{size}` is not required for decoding, but can be used to skip sections when navigating through a binary. The module is malformed if the size does not match the length of the binary contents :math:`\B{B}`. The following section ids are used: == =============================================== Id Section == =============================================== 0 :ref:`custom section ` 1 :ref:`type section ` 2 :ref:`import section ` 3 :ref:`function section ` 4 :ref:`table section ` 5 :ref:`memory section ` 6 :ref:`global section ` 7 :ref:`export section ` 8 :ref:`start section ` 9 :ref:`element section ` 10 :ref:`code section ` 11 :ref:`data section ` 12 :ref:`data count section ` == =============================================== .. index:: ! custom section pair: binary format; custom section single: section; custom .. _binary-customsec: Custom Section ~~~~~~~~~~~~~~ *Custom sections* have the id 0. They are intended to be used for debugging information or third-party extensions, and are ignored by the WebAssembly semantics. Their contents consist of a :ref:`name ` further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use. .. math:: \begin{array}{llclll} \production{custom section} & \Bcustomsec &::=& \Bsection_0(\Bcustom) \\ \production{custom data} & \Bcustom &::=& \Bname~~\Bbyte^\ast \\ \end{array} .. note:: If an implementation interprets the data of a custom section, then errors in that data, or the placement of the section, must not invalidate the module. .. index:: ! type section, type definition pair: binary format; type section pair: section; type .. _binary-typedef: .. _binary-typesec: Type Section ~~~~~~~~~~~~ The *type section* has the id 1. It decodes into a vector of :ref:`function types ` that represent the |MTYPES| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{type section} & \Btypesec &::=& \X{ft}^\ast{:\,}\Bsection_1(\Bvec(\Bfunctype)) &\Rightarrow& \X{ft}^\ast \\ \end{array} .. index:: ! import section, import, name, function type, table type, memory type, global type pair: binary format; import pair: section; import .. _binary-import: .. _binary-importdesc: .. _binary-importsec: Import Section ~~~~~~~~~~~~~~ The *import section* has the id 2. It decodes into a vector of :ref:`imports ` that represent the |MIMPORTS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{import section} & \Bimportsec &::=& \X{im}^\ast{:}\Bsection_2(\Bvec(\Bimport)) &\Rightarrow& \X{im}^\ast \\ \production{import} & \Bimport &::=& \X{mod}{:}\Bname~~\X{nm}{:}\Bname~~d{:}\Bimportdesc &\Rightarrow& \{ \IMODULE~\X{mod}, \INAME~\X{nm}, \IDESC~d \} \\ \production{import description} & \Bimportdesc &::=& \hex{00}~~x{:}\Btypeidx &\Rightarrow& \IDFUNC~x \\ &&|& \hex{01}~~\X{tt}{:}\Btabletype &\Rightarrow& \IDTABLE~\X{tt} \\ &&|& \hex{02}~~\X{mt}{:}\Bmemtype &\Rightarrow& \IDMEM~\X{mt} \\ &&|& \hex{03}~~\X{gt}{:}\Bglobaltype &\Rightarrow& \IDGLOBAL~\X{gt} \\ \end{array} .. index:: ! function section, function, type index, function type pair: binary format; function pair: section; function .. _binary-funcsec: Function Section ~~~~~~~~~~~~~~~~ The *function section* has the id 3. It decodes into a vector of :ref:`type indices ` that represent the |FTYPE| fields of the :ref:`functions ` in the |MFUNCS| component of a :ref:`module `. The |FLOCALS| and |FBODY| fields of the respective functions are encoded separately in the :ref:`code section `. .. math:: \begin{array}{llclll} \production{function section} & \Bfuncsec &::=& x^\ast{:}\Bsection_3(\Bvec(\Btypeidx)) &\Rightarrow& x^\ast \\ \end{array} .. index:: ! table section, table, table type pair: binary format; table pair: section; table .. _binary-table: .. _binary-tablesec: Table Section ~~~~~~~~~~~~~ The *table section* has the id 4. It decodes into a vector of :ref:`tables ` that represent the |MTABLES| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{table section} & \Btablesec &::=& \X{tab}^\ast{:}\Bsection_4(\Bvec(\Btable)) &\Rightarrow& \X{tab}^\ast \\ \production{table} & \Btable &::=& \X{tt}{:}\Btabletype &\Rightarrow& \{ \TTYPE~\X{tt} \} \\ \end{array} .. index:: ! memory section, memory, memory type pair: binary format; memory pair: section; memory .. _binary-mem: .. _binary-memsec: Memory Section ~~~~~~~~~~~~~~ The *memory section* has the id 5. It decodes into a vector of :ref:`memories ` that represent the |MMEMS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{memory section} & \Bmemsec &::=& \X{mem}^\ast{:}\Bsection_5(\Bvec(\Bmem)) &\Rightarrow& \X{mem}^\ast \\ \production{memory} & \Bmem &::=& \X{mt}{:}\Bmemtype &\Rightarrow& \{ \MTYPE~\X{mt} \} \\ \end{array} .. index:: ! global section, global, global type, expression pair: binary format; global pair: section; global .. _binary-global: .. _binary-globalsec: Global Section ~~~~~~~~~~~~~~ The *global section* has the id 6. It decodes into a vector of :ref:`globals ` that represent the |MGLOBALS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{global section} & \Bglobalsec &::=& \X{glob}^\ast{:}\Bsection_6(\Bvec(\Bglobal)) &\Rightarrow& \X{glob}^\ast \\ \production{global} & \Bglobal &::=& \X{gt}{:}\Bglobaltype~~e{:}\Bexpr &\Rightarrow& \{ \GTYPE~\X{gt}, \GINIT~e \} \\ \end{array} .. index:: ! export section, export, name, index, function index, table index, memory index, global index pair: binary format; export pair: section; export .. _binary-export: .. _binary-exportdesc: .. _binary-exportsec: Export Section ~~~~~~~~~~~~~~ The *export section* has the id 7. It decodes into a vector of :ref:`exports ` that represent the |MEXPORTS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{export section} & \Bexportsec &::=& \X{ex}^\ast{:}\Bsection_7(\Bvec(\Bexport)) &\Rightarrow& \X{ex}^\ast \\ \production{export} & \Bexport &::=& \X{nm}{:}\Bname~~d{:}\Bexportdesc &\Rightarrow& \{ \ENAME~\X{nm}, \EDESC~d \} \\ \production{export description} & \Bexportdesc &::=& \hex{00}~~x{:}\Bfuncidx &\Rightarrow& \EDFUNC~x \\ &&|& \hex{01}~~x{:}\Btableidx &\Rightarrow& \EDTABLE~x \\ &&|& \hex{02}~~x{:}\Bmemidx &\Rightarrow& \EDMEM~x \\ &&|& \hex{03}~~x{:}\Bglobalidx &\Rightarrow& \EDGLOBAL~x \\ \end{array} .. index:: ! start section, start function, function index pair: binary format; start function single: section; start single: start function; section .. _binary-start: .. _binary-startsec: Start Section ~~~~~~~~~~~~~ The *start section* has the id 8. It decodes into an optional :ref:`start function ` that represents the |MSTART| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{start section} & \Bstartsec &::=& \X{st}^?{:}\Bsection_8(\Bstart) &\Rightarrow& \X{st}^? \\ \production{start function} & \Bstart &::=& x{:}\Bfuncidx &\Rightarrow& \{ \SFUNC~x \} \\ \end{array} .. index:: ! element section, element, table index, expression, function index pair: binary format; element pair: section; element single: table; element single: element; segment .. _binary-elem: .. _binary-elemsec: .. _binary-elemkind: Element Section ~~~~~~~~~~~~~~~ The *element section* has the id 9. It decodes into a vector of :ref:`element segments ` that represent the |MELEMS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{element section} & \Belemsec &::=& \X{seg}^\ast{:}\Bsection_9(\Bvec(\Belem)) &\Rightarrow& \X{seg} \\ \production{element segment} & \Belem &::=& \hex{00}~~e{:}\Bexpr~~y^\ast{:}\Bvec(\Bfuncidx) &\Rightarrow& \{ \ETYPE~\FUNCREF, \EINIT~((\REFFUNC~y)~\END)^\ast, \EMODE~\EACTIVE~\{ \ETABLE~0, \EOFFSET~e \} \} \\ &&|& \hex{01}~~\X{et}:\Belemkind~~y^\ast{:}\Bvec(\Bfuncidx) &\Rightarrow& \{ \ETYPE~\X{et}, \EINIT~((\REFFUNC~y)~\END)^\ast, \EMODE~\EPASSIVE \} \\ &&|& \hex{02}~~x{:}\Btableidx~~e{:}\Bexpr~~\X{et}:\Belemkind~~y^\ast{:}\Bvec(\Bfuncidx) &\Rightarrow& \{ \ETYPE~\X{et}, \EINIT~((\REFFUNC~y)~\END)^\ast, \EMODE~\EACTIVE~\{ \ETABLE~x, \EOFFSET~e \} \} \\ &&|& \hex{03}~~\X{et}:\Belemkind~~y^\ast{:}\Bvec(\Bfuncidx) &\Rightarrow& \{ \ETYPE~\X{et}, \EINIT~((\REFFUNC~y)~\END)^\ast, \EMODE~\EDECLARATIVE \} \\ &&|& \hex{04}~~e{:}\Bexpr~~\X{el}^\ast{:}\Bvec(\Bexpr) &\Rightarrow& \{ \ETYPE~\FUNCREF, \EINIT~\X{el}^\ast, \EMODE~\EACTIVE~\{ \ETABLE~0, \EOFFSET~e \} \} \\ &&|& \hex{05}~~\X{et}:\Breftype~~\X{el}^\ast{:}\Bvec(\Bexpr) &\Rightarrow& \{ \ETYPE~et, \EINIT~\X{el}^\ast, \EMODE~\EPASSIVE \} \\ &&|& \hex{06}~~x{:}\Btableidx~~e{:}\Bexpr~~\X{et}:\Breftype~~\X{el}^\ast{:}\Bvec(\Bexpr) &\Rightarrow& \{ \ETYPE~et, \EINIT~\X{el}^\ast, \EMODE~\EACTIVE~\{ \ETABLE~x, \EOFFSET~e \} \} \\ &&|& \hex{07}~~\X{et}:\Breftype~~\X{el}^\ast{:}\Bvec(\Bexpr) &\Rightarrow& \{ \ETYPE~et, \EINIT~\X{el}^\ast, \EMODE~\EDECLARATIVE \} \\ \production{element kind} & \Belemkind &::=& \hex{00} &\Rightarrow& \FUNCREF \\ \end{array} .. note:: The initial byte can be interpreted as a bitfield. Bit 0 indicates a passive or declarative segment, bit 1 indicates the presence of an explicit table index for an active segment and otherwise distinguishes passive from declarative segments, bit 2 indicates the use of element type and element :ref:`expressions ` instead of element kind and element indices. Additional element kinds may be added in future versions of WebAssembly. .. index:: ! code section, function, local, type index, function type pair: binary format; function pair: binary format; local pair: section; code .. _binary-code: .. _binary-func: .. _binary-local: .. _binary-codesec: Code Section ~~~~~~~~~~~~ The *code section* has the id 10. It decodes into a vector of *code* entries that are pairs of :ref:`value type ` vectors and :ref:`expressions `. They represent the |FLOCALS| and |FBODY| field of the :ref:`functions ` in the |MFUNCS| component of a :ref:`module `. The |FTYPE| fields of the respective functions are encoded separately in the :ref:`function section `. The encoding of each code entry consists of * the |U32| *size* of the function code in bytes, * the actual *function code*, which in turn consists of * the declaration of *locals*, * the function *body* as an :ref:`expression `. Local declarations are compressed into a vector whose entries consist of * a |U32| *count*, * a :ref:`value type `, denoting *count* locals of the same value type. .. math:: \begin{array}{llclll@{\qquad}l} \production{code section} & \Bcodesec &::=& \X{code}^\ast{:}\Bsection_{10}(\Bvec(\Bcode)) &\Rightarrow& \X{code}^\ast \\ \production{code} & \Bcode &::=& \X{size}{:}\Bu32~~\X{code}{:}\Bfunc &\Rightarrow& \X{code} & (\iff \X{size} = ||\Bfunc||) \\ \production{function} & \Bfunc &::=& (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr &\Rightarrow& \concat((t^\ast)^\ast), e^\ast & (\iff |\concat((t^\ast)^\ast)| < 2^{32}) \\ \production{locals} & \Blocals &::=& n{:}\Bu32~~t{:}\Bvaltype &\Rightarrow& t^n \\ \end{array} Here, :math:`\X{code}` ranges over pairs :math:`(\valtype^\ast, \expr)`. The meta function :math:`\concat((t^\ast)^\ast)` concatenates all sequences :math:`t_i^\ast` in :math:`(t^\ast)^\ast`. Any code for which the length of the resulting sequence is out of bounds of the maximum size of a :ref:`vector ` is malformed. .. note:: Like with :ref:`sections `, the code :math:`\X{size}` is not needed for decoding, but can be used to skip functions when navigating through a binary. The module is malformed if a size does not match the length of the respective function code. .. index:: ! data section, data, memory, memory index, expression, byte pair: binary format; data pair: section; data single: memory; data single: data; segment .. _binary-data: .. _binary-datasec: Data Section ~~~~~~~~~~~~ The *data section* has the id 11. It decodes into a vector of :ref:`data segments ` that represent the |MDATAS| component of a :ref:`module `. .. math:: \begin{array}{llclll} \production{data section} & \Bdatasec &::=& \X{seg}^\ast{:}\Bsection_{11}(\Bvec(\Bdata)) &\Rightarrow& \X{seg} \\ \production{data segment} & \Bdata &::=& \hex{00}~~e{:}\Bexpr~~b^\ast{:}\Bvec(\Bbyte) &\Rightarrow& \{ \DINIT~b^\ast, \DMODE~\DACTIVE~\{ \DMEM~0, \DOFFSET~e \} \} \\ &&|& \hex{01}~~b^\ast{:}\Bvec(\Bbyte) &\Rightarrow& \{ \DINIT~b^\ast, \DMODE~\DPASSIVE \} \\ &&|& \hex{02}~~x{:}\Bmemidx~~e{:}\Bexpr~~b^\ast{:}\Bvec(\Bbyte) &\Rightarrow& \{ \DINIT~b^\ast, \DMODE~\DACTIVE~\{ \DMEM~x, \DOFFSET~e \} \} \\ \end{array} .. note:: The initial byte can be interpreted as a bitfield. Bit 0 indicates a passive segment, bit 1 indicates the presence of an explicit memory index for an active segment. In the current version of WebAssembly, at most one memory may be defined or imported in a single module, so all valid :ref:`active ` data segments have a |DMEM| value of :math:`0`. .. index:: ! data count section, data count, data segment pair: binary format; data count pair: section; data count .. _binary-datacountsec: Data Count Section ~~~~~~~~~~~~~~~~~~ The *data count section* has the id 12. It decodes into an optional :ref:`u32 ` that represents the number of :ref:`data segments ` in the :ref:`data section `. If this count does not match the length of the data segment vector, the module is malformed. .. math:: \begin{array}{llclll} \production{data count section} & \Bdatacountsec &::=& \X{n}^?{:}\Bsection_{12}(\Bu32) &\Rightarrow& \X{n}^? \\ \end{array} .. note:: The data count section is used to simplify single-pass validation. Since the data section occurs after the code section, the :math:`\MEMORYINIT` and :math:`\DATADROP` instructions would not be able to check whether the data segment index is valid until the data section is read. The data count section occurs before the code section, so a single-pass validator can use this count instead of deferring validation. .. index:: module, section, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version pair: binary format; module .. _binary-magic: .. _binary-version: .. _binary-module: Modules ~~~~~~~ The encoding of a :ref:`module ` starts with a preamble containing a 4-byte magic number (the string :math:`\text{\backslash0asm}`) and a version field. The current version of the WebAssembly binary format is 1. The preamble is followed by a sequence of :ref:`sections `. :ref:`Custom sections ` may be inserted at any place in this sequence, while other sections must occur at most once and in the prescribed order. All sections can be empty. The lengths of vectors produced by the (possibly empty) :ref:`function ` and :ref:`code ` section must match up. Similarly, the optional data count must match the length of the :ref:`data segment ` vector. Furthermore, it must be present if any :math:`data index ` occurs in the code section. .. math:: \begin{array}{llcllll} \production{magic} & \Bmagic &::=& \hex{00}~\hex{61}~\hex{73}~\hex{6D} \\ \production{version} & \Bversion &::=& \hex{01}~\hex{00}~\hex{00}~\hex{00} \\ \production{module} & \Bmodule &::=& \Bmagic \\ &&& \Bversion \\ &&& \Bcustomsec^\ast \\ &&& \functype^\ast{:\,}\Btypesec \\ &&& \Bcustomsec^\ast \\ &&& \import^\ast{:\,}\Bimportsec \\ &&& \Bcustomsec^\ast \\ &&& \typeidx^n{:\,}\Bfuncsec \\ &&& \Bcustomsec^\ast \\ &&& \table^\ast{:\,}\Btablesec \\ &&& \Bcustomsec^\ast \\ &&& \mem^\ast{:\,}\Bmemsec \\ &&& \Bcustomsec^\ast \\ &&& \global^\ast{:\,}\Bglobalsec \\ &&& \Bcustomsec^\ast \\ &&& \export^\ast{:\,}\Bexportsec \\ &&& \Bcustomsec^\ast \\ &&& \start^?{:\,}\Bstartsec \\ &&& \Bcustomsec^\ast \\ &&& \elem^\ast{:\,}\Belemsec \\ &&& \Bcustomsec^\ast \\ &&& m^?{:\,}\Bdatacountsec \\ &&& \Bcustomsec^\ast \\ &&& \X{code}^n{:\,}\Bcodesec \\ &&& \Bcustomsec^\ast \\ &&& \data^m{:\,}\Bdatasec \\ &&& \Bcustomsec^\ast \quad\Rightarrow\quad \{~ \begin{array}[t]{@{}l@{}} \MTYPES~\functype^\ast, \\ \MFUNCS~\func^n, \\ \MTABLES~\table^\ast, \\ \MMEMS~\mem^\ast, \\ \MGLOBALS~\global^\ast, \\ \MELEMS~\elem^\ast, \\ \MDATAS~\data^m, \\ \MSTART~\start^?, \\ \MIMPORTS~\import^\ast, \\ \MEXPORTS~\export^\ast ~\} \\ \end{array} \\ &&& (\iff m^? \neq \epsilon \vee \freedataidx(\X{code}^n) = \emptyset) \\ \end{array} where for each :math:`t_i^\ast, e_i` in :math:`\X{code}^n`, .. math:: \func^n[i] = \{ \FTYPE~\typeidx^n[i], \FLOCALS~t_i^\ast, \FBODY~e_i \} ) \\ .. note:: The version of the WebAssembly binary format may increase in the future if backward-incompatible changes have to be made to the format. However, such changes are expected to occur very infrequently, if ever. The binary format is intended to be forward-compatible, such that future extensions can be made without incrementing its version. ================================================ FILE: document/core/binary/types.rst ================================================ .. index:: type pair: binary format; type .. _binary-type: Types ----- .. note:: In future versions of WebAssembly, value types may include types denoted by :ref:`type indices `. Thus, the binary format for types corresponds to the encodings of small negative :math:`\xref{binary/values}{binary-sint}{\sN}` values, so that they can coexist with (positive) type indices in the future. .. index:: number type pair: binary format; number type .. _binary-numtype: Number Types ~~~~~~~~~~~~ :ref:`Number types ` are encoded by a single byte. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{number type} & \Bnumtype &::=& \hex{7F} &\Rightarrow& \I32 \\ &&|& \hex{7E} &\Rightarrow& \I64 \\ &&|& \hex{7D} &\Rightarrow& \F32 \\ &&|& \hex{7C} &\Rightarrow& \F64 \\ \end{array} .. index:: reference type pair: binary format; reference type .. _binary-reftype: Reference Types ~~~~~~~~~~~~~~~ :ref:`Reference types ` are also encoded by a single byte. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{reference type} & \Breftype &::=& \hex{70} &\Rightarrow& \FUNCREF \\ &&|& \hex{6F} &\Rightarrow& \EXTERNREF \\ \end{array} .. index:: value type, number type, reference type pair: binary format; value type .. _binary-valtype: Value Types ~~~~~~~~~~~ :ref:`Value types ` are encoded with their respective encoding as a :ref:`number type ` or :ref:`reference type `. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{value type} & \Bvaltype &::=& t{:}\Bnumtype &\Rightarrow& t \\ &&|& t{:}\Breftype &\Rightarrow& t \\ \end{array} .. note:: Value types can occur in contexts where :ref:`type indices ` are also allowed, such as in the case of :ref:`block types `. Thus, the binary format for types corresponds to the |SignedLEB128|_ :ref:`encoding ` of small negative :math:`\sN` values, so that they can coexist with (positive) type indices in the future. .. index:: result type, value type pair: binary format; result type .. _binary-resulttype: Result Types ~~~~~~~~~~~~ :ref:`Result types ` are encoded by the respective :ref:`vectors ` of :ref:`value types ``. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{result type} & \Bresulttype &::=& t^\ast{:\,}\Bvec(\Bvaltype) &\Rightarrow& [t^\ast] \\ \end{array} .. index:: function type, value type, result type pair: binary format; function type .. _binary-functype: Function Types ~~~~~~~~~~~~~~ :ref:`Function types ` are encoded by the byte :math:`\hex{60}` followed by the respective :ref:`vectors ` of parameter and result types. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{function type} & \Bfunctype &::=& \hex{60}~~\X{rt}_1{:\,}\Bresulttype~~\X{rt}_2{:\,}\Bresulttype &\Rightarrow& \X{rt}_1 \to \X{rt}_2 \\ \end{array} .. index:: limits pair: binary format; limits .. _binary-limits: Limits ~~~~~~ :ref:`Limits ` are encoded with a preceding flag indicating whether a maximum is present. .. math:: \begin{array}{llclll} \production{limits} & \Blimits &::=& \hex{00}~~n{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~\epsilon \} \\ &&|& \hex{01}~~n{:}\Bu32~~m{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~m \} \\ \end{array} .. index:: memory type, limits, page size pair: binary format; memory type .. _binary-memtype: Memory Types ~~~~~~~~~~~~ :ref:`Memory types ` are encoded with their :ref:`limits `. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{memory type} & \Bmemtype &::=& \X{lim}{:}\Blimits &\Rightarrow& \X{lim} \\ \end{array} .. index:: table type, reference type, limits pair: binary format; table type .. _binary-tabletype: Table Types ~~~~~~~~~~~ :ref:`Table types ` are encoded with their :ref:`limits ` and the encoding of their element :ref:`reference type `. .. math:: \begin{array}{llclll} \production{table type} & \Btabletype &::=& \X{et}{:}\Breftype~~\X{lim}{:}\Blimits &\Rightarrow& \X{lim}~\X{et} \\ \end{array} .. index:: global type, mutability, value type pair: binary format; global type pair: binary format; mutability .. _binary-mut: .. _binary-globaltype: Global Types ~~~~~~~~~~~~ :ref:`Global types ` are encoded by their :ref:`value type ` and a flag for their :ref:`mutability `. .. math:: \begin{array}{llclll} \production{global type} & \Bglobaltype &::=& t{:}\Bvaltype~~m{:}\Bmut &\Rightarrow& m~t \\ \production{mutability} & \Bmut &::=& \hex{00} &\Rightarrow& \MCONST \\ &&|& \hex{01} &\Rightarrow& \MVAR \\ \end{array} ================================================ FILE: document/core/binary/values.rst ================================================ .. index:: value pair: binary format; value .. _binary-value: Values ------ .. index:: byte pair: binary format; byte .. _binary-byte: Bytes ~~~~~ :ref:`Bytes ` encode themselves. .. math:: \begin{array}{llcll@{\qquad}l} \production{byte} & \Bbyte &::=& \hex{00} &\Rightarrow& \hex{00} \\ &&|&& \dots \\ &&|& \hex{FF} &\Rightarrow& \hex{FF} \\ \end{array} .. index:: integer, unsigned integer, signed integer, uninterpreted integer, LEB128, two's complement pair: binary format; integer pair: binary format; unsigned integer pair: binary format; signed integer pair: binary format; uninterpreted integer .. _binary-sint: .. _binary-uint: .. _binary-int: Integers ~~~~~~~~ All :ref:`integers ` are encoded using the |LEB128|_ variable-length integer encoding, in either unsigned or signed variant. :ref:`Unsigned integers ` are encoded in |UnsignedLEB128|_ format. As an additional constraint, the total number of bytes encoding a value of type :math:`\uN` must not exceed :math:`\F{ceil}(N/7)` bytes. .. math:: \begin{array}{llclll@{\qquad}l} \production{unsigned integer} & \BuN &::=& n{:}\Bbyte &\Rightarrow& n & (\iff n < 2^7 \wedge n < 2^N) \\ &&|& n{:}\Bbyte~~m{:}\BuX{(N\B{-7})} &\Rightarrow& 2^7\cdot m + (n-2^7) & (\iff n \geq 2^7 \wedge N > 7) \\ \end{array} :ref:`Signed integers ` are encoded in |SignedLEB128|_ format, which uses a two's complement representation. As an additional constraint, the total number of bytes encoding a value of type :math:`\sN` must not exceed :math:`\F{ceil}(N/7)` bytes. .. math:: \begin{array}{llclll@{\qquad}l} \production{signed integer} & \BsN &::=& n{:}\Bbyte &\Rightarrow& n & (\iff n < 2^6 \wedge n < 2^{N-1}) \\ &&|& n{:}\Bbyte &\Rightarrow& n-2^7 & (\iff 2^6 \leq n < 2^7 \wedge n \geq 2^7-2^{N-1}) \\ &&|& n{:}\Bbyte~~m{:}\BsX{(N\B{-7})} &\Rightarrow& 2^7\cdot m + (n-2^7) & (\iff n \geq 2^7 \wedge N > 7) \\ \end{array} :ref:`Uninterpreted integers ` are encoded as signed integers. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{uninterpreted integer} & \BiN &::=& n{:}\BsN &\Rightarrow& i & (\iff n = \signed_{\iN}(i)) \end{array} .. note:: The side conditions :math:`N > 7` in the productions for non-terminal bytes of the :math:`\uX{}` and :math:`\sX{}` encodings restrict the encoding's length. However, "trailing zeros" are still allowed within these bounds. For example, :math:`\hex{03}` and :math:`\hex{83}~\hex{00}` are both well-formed encodings for the value :math:`3` as a |u8|. Similarly, either of :math:`\hex{7e}` and :math:`\hex{FE}~\hex{7F}` and :math:`\hex{FE}~\hex{FF}~\hex{7F}` are well-formed encodings of the value :math:`-2` as a |s16|. The side conditions on the value :math:`n` of terminal bytes further enforce that any unused bits in these bytes must be :math:`0` for positive values and :math:`1` for negative ones. For example, :math:`\hex{83}~\hex{10}` is malformed as a |u8| encoding. Similarly, both :math:`\hex{83}~\hex{3E}` and :math:`\hex{FF}~\hex{7B}` are malformed as |s8| encodings. .. index:: floating-point number, little endian pair: binary format; floating-point number .. _binary-float: Floating-Point ~~~~~~~~~~~~~~ :ref:`Floating-point ` values are encoded directly by their |IEEE754|_ (Section 3.4) bit pattern in |LittleEndian|_ byte order: .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{floating-point value} & \BfN &::=& b^\ast{:\,}\Bbyte^{N/8} &\Rightarrow& \bytes_{\fN}^{-1}(b^\ast) \\ \end{array} .. index:: name, byte, Unicode, ! UTF-8 pair: binary format; name .. _binary-utf8: .. _binary-name: Names ~~~~~ :ref:`Names ` are encoded as a :ref:`vector ` of bytes containing the |Unicode|_ (Section 3.9) UTF-8 encoding of the name's character sequence. .. math:: \begin{array}{llclllll} \production{name} & \Bname &::=& b^\ast{:}\Bvec(\Bbyte) &\Rightarrow& \name && (\iff \utf8(\name) = b^\ast) \\ \end{array} The auxiliary |utf8| function expressing this encoding is defined as follows: .. math:: \begin{array}{@{}l@{}} \begin{array}{@{}lcl@{\qquad}l@{}} \utf8(c^\ast) &=& (\utf8(c))^\ast \\[1ex] \utf8(c) &=& b & (\begin{array}[t]{@{}c@{~}l@{}} \iff & c < \unicode{80} \\ \wedge & c = b) \\ \end{array} \\ \utf8(c) &=& b_1~b_2 & (\begin{array}[t]{@{}c@{~}l@{}} \iff & \unicode{80} \leq c < \unicode{800} \\ \wedge & c = 2^6(b_1-\hex{C0})+(b_2-\hex{80})) \\ \end{array} \\ \utf8(c) &=& b_1~b_2~b_3 & (\begin{array}[t]{@{}c@{~}l@{}} \iff & \unicode{800} \leq c < \unicode{D800} \vee \unicode{E000} \leq c < \unicode{10000} \\ \wedge & c = 2^{12}(b_1-\hex{E0})+2^6(b_2-\hex{80})+(b_3-\hex{80})) \\ \end{array} \\ \utf8(c) &=& b_1~b_2~b_3~b_4 & (\begin{array}[t]{@{}c@{~}l@{}} \iff & \unicode{10000} \leq c < \unicode{110000} \\ \wedge & c = 2^{18}(b_1-\hex{F0})+2^{12}(b_2-\hex{80})+2^6(b_3-\hex{80})+(b_4-\hex{80})) \\ \end{array} \\ \end{array} \\ \where b_2, b_3, b_4 < \hex{C0} \\ \end{array} .. note:: Unlike in some other formats, name strings are not 0-terminated. ================================================ FILE: document/core/conf.py ================================================ # -*- coding: utf-8 -*- # # WebAssembly documentation build configuration file, created by # sphinx-quickstart on Mon Nov 21 11:32:49 2016. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. import os import sys pwd = os.path.abspath('.') sys.path.insert(0, pwd + '/util') # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.4' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', 'sphinx.ext.ifconfig', 'sphinx.ext.githubpages', 'mathdef', 'pseudo-lexer' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst'] # The encoding of source files. # # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. name = 'WebAssembly' project = u'WebAssembly' title = u'WebAssembly Specification' copyright = u'2017, WebAssembly Community Group' author = u'WebAssembly Community Group' editor = u'Andreas Rossberg (editor)' logo = 'static/webassembly.png' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = u'1.1' # The full version, including alpha/beta/rc tags. release = version + '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # # today = '' # # Else, today_fmt is used as the format for a strftime call. # # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The reST default role (used for this markup: `text`) to use for all # documents. # # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = { 'logo': logo, 'logo_name': 'WebAssembly', 'description': 'WebAssembly Specification', 'fixed_sidebar': True, 'sidebar_width': '260px', 'sidebar_collapse': True, 'show_powered_by': False, 'extra_nav_links': { 'Index': 'BASEDIR/genindex.html', 'Download as PDF': 'BASEDIR/_download/' + name + '.pdf' }, } html_sidebars = { '**': [ # 'about.html', 'navigation.html', # 'relations.html', 'searchbox.html', ] } # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. # html_title = project + u' ' + release # A shorter title for the navigation bar. Default is the same as html_title. # # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = logo # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static', 'static/custom.css'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # # html_extra_path = [] # If not None, a 'Last updated on:' timestamp is inserted at every page # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. # # html_last_updated_fmt = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # # html_use_smartypants = True # Additional templates that should be rendered to pages, maps page names to # template names. # # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = False # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, the reST sources are included in the HTML build as _sources/name. The default is True. # html_copy_source = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = False # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If this is not None, a ‘Last updated on:’ timestamp is inserted at every # page bottom, using the given strftime() format. # html_last_updated_fmt = '%F' # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # # html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' # # html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # 'ja' uses this config value. # 'zh' user can custom change `jieba` dictionary path. # # html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. # # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. # htmlhelp_basename = 'WebAssemblydoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('a4paper' or 'letterpaper'). 'papersize': 'a4paper', # The font size ('10pt', '11pt' or '12pt'). 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. 'preamble': '', # Latex figure (float) alignment 'figure_align': 'htbp', # Fancy chapters [Bjarne, Sonny, Lenny, Glenn, Conny, Rejne] 'fncychap': '\\usepackage[Sonny]{fncychap}', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ( master_doc, name + '.tex', title, author + '\\\\ \\hfill\\large ' + editor, 'manual' ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = logo # For "manual" documents [part, chapter, or section]. # latex_toplevel_sectioning = 'chapter' # If true, show page references after internal links. # latex_show_pagerefs = False # How to show URL addresses after external links [no, footnote, inline]. # latex_show_urls = 'footnote' # Documents to append as an appendix to all manuals. # # latex_appendices = [] # It false, will not define \strong, \code, \titleref, \crossref ... but only # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added # packages. # # latex_keep_old_macro_names = True # If false, no module index is generated. # latex_domain_indices = False # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ( master_doc, name, title, [author], 1 ) ] # If true, show URL addresses after external links. # # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, name, title, author, name, 'A portable low-level execution format.', 'Virtual Machine' ), ] # Documents to append as an appendix to all manuals. # # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = False # How to display URL addresses: 'footnote', 'no', or 'inline'. # # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # # texinfo_no_detailmenu = False # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. epub_title = project epub_author = author epub_publisher = author epub_copyright = copyright # The basename for the epub file. It defaults to the project name. # epub_basename = project # The HTML theme for the epub output. Since the default themes are not # optimized for small screen space, using the same theme for HTML and epub # output is usually not wise. This defaults to 'epub', a theme designed to save # visual space. # # epub_theme = 'epub' # The language of the text. It defaults to the language option # or 'en' if the language is not set. # # epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. # epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. # # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A tuple containing the cover image and cover page html template filenames. # # epub_cover = () # A sequence of (type, uri, title) tuples for the guide element of content.opf. # # epub_guide = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. # # epub_pre_files = [] # HTML files that should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. # # epub_post_files = [] # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # The depth of the table of contents in toc.ncx. # # epub_tocdepth = 3 # Allow duplicate toc entries. # # epub_tocdup = True # Choose between 'default' and 'includehidden'. # # epub_tocscope = 'default' # Fix unsupported image types using the Pillow. # # epub_fix_images = False # Scale large images. # # epub_max_image_width = 0 # How to display URL addresses: 'footnote', 'no', or 'inline'. # # epub_show_urls = 'inline' # If false, no index is generated. # # epub_use_index = True # Macros rst_prolog = """ .. include:: /""" + pwd + """/util/macros.def """ # https://www.sphinx-doc.org/en/master/usage/extensions/math.html#confval-mathjax_config # http://docs.mathjax.org/en/v2.7-latest/options/input-processors/TeX.html mathjax_config = { 'TeX': { 'MAXBUFFER': 30*1024 }, } ================================================ FILE: document/core/exec/conventions.rst ================================================ .. index:: ! execution, stack, store Conventions ----------- WebAssembly code is *executed* when :ref:`instantiating ` a module or :ref:`invoking ` an :ref:`exported ` function on the resulting module :ref:`instance `. Execution behavior is defined in terms of an *abstract machine* that models the *program state*. It includes a *stack*, which records operand values and control constructs, and an abstract *store* containing global state. For each instruction, there is a rule that specifies the effect of its execution on the program state. Furthermore, there are rules describing the instantiation of a module. As with :ref:`validation `, all rules are given in two *equivalent* forms: 1. In *prose*, describing the execution in intuitive form. 2. In *formal notation*, describing the rule in mathematical form. [#cite-pldi2017]_ .. note:: As with validation, the prose and formal rules are equivalent, so that understanding of the formal notation is *not* required to read this specification. The formalism offers a more concise description in notation that is used widely in programming languages semantics and is readily amenable to mathematical proof. .. _exec-notation-textual: Prose Notation ~~~~~~~~~~~~~~ Execution is specified by stylised, step-wise rules for each :ref:`instruction ` of the :ref:`abstract syntax `. The following conventions are adopted in stating these rules. * The execution rules implicitly assume a given :ref:`store ` :math:`S`. * The execution rules also assume the presence of an implicit :ref:`stack ` that is modified by *pushing* or *popping* :ref:`values `, :ref:`labels `, and :ref:`frames `. * Certain rules require the stack to contain at least one frame. The most recent frame is referred to as the *current* frame. * Both the store and the current frame are mutated by *replacing* some of their components. Such replacement is assumed to apply globally. * The execution of an instruction may *trap*, in which case the entire computation is aborted and no further modifications to the store are performed by it. (Other computations can still be initiated afterwards.) * The execution of an instruction may also end in a *jump* to a designated target, which defines the next instruction to execute. * Execution can *enter* and *exit* :ref:`instruction sequences ` that form :ref:`blocks `. * :ref:`Instruction sequences ` are implicitly executed in order, unless a trap or jump occurs. * In various places the rules contain *assertions* expressing crucial invariants about the program state. .. index:: ! reduction rules, configuration, evaluation context .. _exec-notation: Formal Notation ~~~~~~~~~~~~~~~ .. note:: This section gives a brief explanation of the notation for specifying execution formally. For the interested reader, a more thorough introduction can be found in respective text books. [#cite-tapl]_ The formal execution rules use a standard approach for specifying operational semantics, rendering them into *reduction rules*. Every rule has the following general form: .. math:: \X{configuration} \quad\stepto\quad \X{configuration} A *configuration* is a syntactic description of a program state. Each rule specifies one *step* of execution. As long as there is at most one reduction rule applicable to a given configuration, reduction -- and thereby execution -- is *deterministic*. WebAssembly has only very few exceptions to this, which are noted explicitly in this specification. For WebAssembly, a configuration typically is a tuple :math:`(S; F; \instr^\ast)` consisting of the current :ref:`store ` :math:`S`, the :ref:`call frame ` :math:`F` of the current function, and the sequence of :ref:`instructions ` that is to be executed. (A more precise definition is given :ref:`later `.) To avoid unnecessary clutter, the store :math:`S` and the frame :math:`F` are omitted from reduction rules that do not touch them. There is no separate representation of the :ref:`stack `. Instead, it is conveniently represented as part of the configuration's instruction sequence. In particular, :ref:`values ` are defined to coincide with |CONST| instructions, and a sequence of |CONST| instructions can be interpreted as an operand "stack" that grows to the right. .. note:: For example, the :ref:`reduction rule ` for the :math:`\I32.\ADD` instruction can be given as follows: .. math:: (\I32.\CONST~n_1)~(\I32.\CONST~n_2)~\I32.\ADD \quad\stepto\quad (\I32.\CONST~(n_1 + n_2) \mod 2^{32}) Per this rule, two |CONST| instructions and the |ADD| instruction itself are removed from the instruction stream and replaced with one new |CONST| instruction. This can be interpreted as popping two value off the stack and pushing the result. When no result is produced, an instruction reduces to the empty sequence: .. math:: \NOP \quad\stepto\quad \epsilon :ref:`Labels