From 5b18d52295bc8fe0cbb9a24065e957a52e744c03 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Mon, 3 Jul 2023 10:52:27 -0500 Subject: [PATCH 01/33] [spec] Add missing type to elem.drop and store soundness (#1668) --- document/core/appendix/properties.rst | 4 ++-- document/core/exec/instructions.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/document/core/appendix/properties.rst b/document/core/appendix/properties.rst index d9b6a3548..3804dd4aa 100644 --- a/document/core/appendix/properties.rst +++ b/document/core/appendix/properties.rst @@ -278,8 +278,8 @@ Module instances are classified by *module contexts*, which are regular :ref:`co .. index:: element instance, reference .. _valid-eleminst: -:ref:`Element Instances ` :math:`\{ \EIELEM~\X{fa}^\ast \}` -............................................................................ +:ref:`Element Instances ` :math:`\{ \EITYPE~t, \EIELEM~\reff^\ast \}` +...................................................................................... * For each :ref:`reference ` :math:`\reff_i` in the elements :math:`\reff^n`: diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index f86349b4e..ccb27bfd3 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -1682,7 +1682,7 @@ Table Instructions 4. Assert: due to :ref:`validation `, :math:`S.\SELEMS[a]` exists. -5. Replace :math:`S.\SELEMS[a]` with the :ref:`element instance ` :math:`\{\EIELEM~\epsilon\}`. +5. Replace :math:`S.\SELEMS[a].\EIELEM` with :math:`\epsilon`. .. math:: ~\\[-1ex] @@ -1691,7 +1691,7 @@ Table Instructions S; F; (\ELEMDROP~x) &\stepto& S'; F; \epsilon \end{array} \\ \qquad - (\iff S' = S \with \SELEMS[F.\AMODULE.\MIELEMS[x]] = \{ \EIELEM~\epsilon \}) \\ + (\iff S' = S \with \SELEMS[F.\AMODULE.\MIELEMS[x]].\EIELEM = \epsilon) \\ \end{array} From 2b00952f3dc2662622a04b113304fc3491178dc0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 11 Jul 2023 06:17:49 -0700 Subject: [PATCH 02/33] [test] Add tests for out-of-range NaN payloads (#1670) --- test/core/float_literals.wast | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/core/float_literals.wast b/test/core/float_literals.wast index fefb91fbb..3b3ed76bb 100644 --- a/test/core/float_literals.wast +++ b/test/core/float_literals.wast @@ -352,6 +352,10 @@ (module quote "(global f32 (f32.const 0x1.0p_+1))") "unknown operator" ) +(assert_malformed + (module quote "(global f32 (f32.const nan:0x80_0000))") + "constant out of range" +) (assert_malformed (module quote "(global f64 (f64.const _100))") @@ -505,3 +509,7 @@ (module quote "(global f64 (f64.const 0x1.0p_+1))") "unknown operator" ) +(assert_malformed + (module quote "(global f64 (f64.const nan:0x10_0000_0000_0000))") + "constant out of range" +) From 539d521ffd313628cbf88049d20a6a67ea84fa09 Mon Sep 17 00:00:00 2001 From: Patrick Dubroy Date: Wed, 12 Jul 2023 20:03:10 +0200 Subject: [PATCH 03/33] [spec] Fix typo (#1671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit depended → dependent --- document/core/binary/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/core/binary/modules.rst b/document/core/binary/modules.rst index e9c72b61a..8e488582d 100644 --- a/document/core/binary/modules.rst +++ b/document/core/binary/modules.rst @@ -60,7 +60,7 @@ 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. +* the actual *contents*, whose structure is dependent on the section id. Every section is optional; an omitted section is equivalent to the section being present with empty contents. From f3a57d973332090f70d32d8333253ff78afca517 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 07:32:12 +0200 Subject: [PATCH 04/33] [spec] Remark about the convention of using a pattern for attribute variable --- document/core/binary/conventions.rst | 1 + document/core/text/conventions.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/document/core/binary/conventions.rst b/document/core/binary/conventions.rst index 83c80399f..7b606e1e4 100644 --- a/document/core/binary/conventions.rst +++ b/document/core/binary/conventions.rst @@ -54,6 +54,7 @@ In order to distinguish symbols of the binary syntax from symbols of the abstrac (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`. + A pattern may also be used instead of a variable, e.g., :math:`7{:}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`. diff --git a/document/core/text/conventions.rst b/document/core/text/conventions.rst index 0bd32e033..1efc88b03 100644 --- a/document/core/text/conventions.rst +++ b/document/core/text/conventions.rst @@ -49,6 +49,7 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra (This is a shorthand for :math:`T^n` where :math:`n \leq 1`.) * :math:`x{:}T` denotes the same language as the nonterminal :math:`T`, but also binds the variable :math:`x` to the attribute synthesized for :math:`T`. + A pattern may also be used instead of a variable, e.g., :math:`(x,y){:}T`. * Productions are written :math:`\T{sym} ::= T_1 \Rightarrow A_1 ~|~ \dots ~|~ T_n \Rightarrow A_n`, where each :math:`A_i` is the attribute that is synthesized for :math:`\T{sym}` in the given case, usually from attribute variables bound in :math:`T_i`. From 3abc5872db2dfac841aea0e8b5de40ed94bcdb5c Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 08:52:44 +0200 Subject: [PATCH 05/33] [interpreter] Bump version to 2.0.1 --- interpreter/main/main.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/main/main.ml b/interpreter/main/main.ml index beeb98049..e626a27de 100644 --- a/interpreter/main/main.ml +++ b/interpreter/main/main.ml @@ -1,5 +1,5 @@ let name = "wasm" -let version = "2.0" +let version = "2.0.1" let configure () = Import.register (Utf8.decode "spectest") Spectest.lookup; From 797cb5e1f709690ac52fa9cf5243661bd92eccf2 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:34:31 +0200 Subject: [PATCH 06/33] [interpreter] Makefile support for opam releases --- interpreter/Makefile | 10 ++++++++++ interpreter/meta/opam/opam | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 interpreter/meta/opam/opam diff --git a/interpreter/Makefile b/interpreter/Makefile index 014b98d55..9caf2a4ac 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -206,3 +206,13 @@ install: _build/$(LIB).cmx _build/$(LIB).cmo uninstall: ocamlfind remove $(LIB) + +opam-release/%: + git tag opam-$* + git push --tags + wget https://github.com/WebAssembly/spec/archive/opam-$*.zip + cp meta/opam/opam . + sed s/@VERSION/$*/g opam >opam.tmp + sed s/@MD5/`md5 -q opam-$*.zip`/g opam.tmp >opam + rm opam.tmp + echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam new file mode 100644 index 000000000..139251f3f --- /dev/null +++ b/interpreter/meta/opam/opam @@ -0,0 +1,22 @@ +opam-version: "2.0" +maintainer: "Andreas Rossberg " +authors: "Andreas Rossberg " +homepage: "https://github.com/WebAssembly/spec" +bug-reports: "https://github.com/WebAssembly/spec/issues" +license: "Apache-2.0" +dev-repo: "git+https://github.com/WebAssembly/spec.git" +build: [ + [make "-C" "interpreter" "opt" "unopt"] +] +install: [make "-C" "interpreter" "install"] +depends: [ + "ocaml" {>= "4.12.0"} + "ocamlfind" {build} + "ocamlbuild" {build} +] +synopsis: + "Library to read and write WebAssembly (Wasm) files and manipulate their AST" +url { + src: "https://github.com/WebAssembly/spec/archive/opam-@VERSION.zip" + checksum: "md5=@MD5" +} From 8a0080afe5ca081c0e6a5c221254cbfd57b02fc4 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:46:23 +0200 Subject: [PATCH 07/33] [interpreter] Makefile tweaks --- interpreter/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 9caf2a4ac..5a6cb64a8 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -208,11 +208,12 @@ uninstall: ocamlfind remove $(LIB) opam-release/%: - git tag opam-$* + #git tag opam-$* git push --tags + rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip cp meta/opam/opam . - sed s/@VERSION/$*/g opam >opam.tmp - sed s/@MD5/`md5 -q opam-$*.zip`/g opam.tmp >opam - rm opam.tmp - echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam + sed -i "tmp" s/@VERSION/$*/g opam + sed -i "tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam + rm opam-$*.zip + @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam From 0bd3aeb7061984f6496923b155e165f25aa8c20b Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:49:12 +0200 Subject: [PATCH 08/33] [interpreter] Makefile tweaks --- interpreter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 5a6cb64a8..aafdb2b8a 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -208,7 +208,7 @@ uninstall: ocamlfind remove $(LIB) opam-release/%: - #git tag opam-$* + git tag opam-$* git push --tags rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip From cfc93439b9b03d0a6decd38353ae03194324c795 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 11:59:40 +0200 Subject: [PATCH 09/33] [interpreter] Tune opam file to fix opam repo CI --- interpreter/Makefile | 6 +++--- interpreter/meta/opam/opam | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index aafdb2b8a..740554d3a 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -213,7 +213,7 @@ opam-release/%: rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip cp meta/opam/opam . - sed -i "tmp" s/@VERSION/$*/g opam - sed -i "tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam - rm opam-$*.zip + sed -i ".tmp" s/@VERSION/$*/g opam + sed -i ".tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam + rm opam.tmp opam-$*.zip @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam index 139251f3f..845fe675e 100644 --- a/interpreter/meta/opam/opam +++ b/interpreter/meta/opam/opam @@ -14,6 +14,7 @@ depends: [ "ocamlfind" {build} "ocamlbuild" {build} ] +conflicts: ["ocaml-option-bytecode-only"] # uses ocamlopt unconconditionally synopsis: "Library to read and write WebAssembly (Wasm) files and manipulate their AST" url { From 653938a88c6f40eb886d5980ca315136eb861d03 Mon Sep 17 00:00:00 2001 From: zapashcanon Date: Wed, 26 Jul 2023 14:14:44 +0200 Subject: [PATCH 10/33] [interpreter] Use dune instead of ocamlbuild (#1665) --- interpreter/.gitignore | 15 +- interpreter/Makefile | 212 +++++++-------------------- interpreter/README.md | 19 +-- interpreter/dune | 31 +++- interpreter/dune-project | 19 +++ interpreter/{meta => }/jslib/wast.ml | 1 + interpreter/meta/findlib/META | 4 - interpreter/meta/opam/opam | 23 --- interpreter/wasm.opam | 32 ++++ interpreter/winmake.bat | 75 ---------- 10 files changed, 137 insertions(+), 294 deletions(-) rename interpreter/{meta => }/jslib/wast.ml (99%) delete mode 100644 interpreter/meta/findlib/META delete mode 100644 interpreter/meta/opam/opam create mode 100644 interpreter/wasm.opam delete mode 100644 interpreter/winmake.bat diff --git a/interpreter/.gitignore b/interpreter/.gitignore index 0a02ff708..ced4eafb6 100644 --- a/interpreter/.gitignore +++ b/interpreter/.gitignore @@ -1,13 +1,6 @@ -*.cmo -*.cmx -*.native -*.byte -*.opt -*.unopt -*.js -*.zip -*.mlpack _build wasm -wasm.debug - +*.install +*.js +*.zip +opam diff --git a/interpreter/Makefile b/interpreter/Makefile index 740554d3a..d67882b29 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -1,4 +1,4 @@ -# This Makefile uses ocamlbuild but does not rely on ocamlfind or the Opam +# This Makefile uses dune but does not rely on ocamlfind or the Opam # package manager to build. However, Opam package management is available # optionally through the check/install/uninstall targets. # @@ -9,131 +9,45 @@ # Configuration -NAME = wasm -UNOPT = $(NAME).debug -OPT = $(NAME) -LIB = $(NAME) +NAME = wasm +OPT = $(NAME).exe ZIP = $(NAME).zip -JSLIB = wast -WINMAKE = winmake.bat - -DIRS = util syntax binary text valid runtime exec script host main tests -LIBS = -FLAGS = -lexflags -ml -cflags '-w +a-4-27-42-44-45-70 -warn-error +a-3' -OCBA = ocamlbuild $(FLAGS) $(DIRS:%=-I %) -OCB = $(OCBA) $(LIBS:%=-libs %) -JSO = js_of_ocaml -q --opt 3 -JS = # set to JS shell command to run JS tests, empty to skip +JSLIB = wast.js +BUILDDIR = _build/default -# Main targets +JS = # set to JS shell command to run JS tests, empty to skip -.PHONY: default opt unopt libopt libunopt jslib all land zip smallint dunebuild -default: opt -debug: unopt -opt: $(OPT) -unopt: $(UNOPT) -libopt: _build/$(LIB).cmx _build/$(LIB).cmxa -libunopt: _build/$(LIB).cmo _build/$(LIB).cma -jslib: $(JSLIB).js -all: unopt opt libunopt libopt test -land: $(WINMAKE) all -zip: $(ZIP) -smallint: smallint.native -ci: land jslib dunebuild +# Main targets -dunebuild: - dune build +.PHONY: default opt jslib all zip smallint +default: $(OPT) +jslib: $(JSLIB) +all: $(OPT) test +zip: $(ZIP) +smallint: smallint.exe +ci: all jslib # Building executable +.PHONY: $(NAME).exe +$(NAME).exe: + rm -f $(NAME) + dune build $@ + cp $(BUILDDIR)/$(OPT) $(NAME) -empty = -space = $(empty) $(empty) -comma = , - -.INTERMEDIATE: _tags -_tags: - echo >$@ "true: bin_annot" - echo >>$@ "true: debug" - echo >>$@ "<{$(subst $(space),$(comma),$(DIRS))}/*.cmx>: for-pack($(PACK))" - -$(UNOPT): main.byte - mv $< $@ - -$(OPT): main.native - mv $< $@ - -.PHONY: main.byte main.native -main.byte: _tags - $(OCB) -quiet $@ - -main.native: _tags - $(OCB) -quiet $@ - -.PHONY: smallint.byte smallint.native -smallint.byte: _tags - $(OCB) -quiet $@ -smallint.native: _tags - $(OCB) -quiet $@ - - -# Building library - -FILES = $(shell ls $(DIRS:%=%/*) | grep '[.]ml[^.]*$$') -PACK = $(shell echo `echo $(LIB) | sed 's/^\(.\).*$$/\\1/g' | tr [:lower:] [:upper:]``echo $(LIB) | sed 's/^.\(.*\)$$/\\1/g'`) - -.INTERMEDIATE: $(LIB).mlpack -$(LIB).mlpack: $(DIRS) - ls $(FILES) \ - | sed 's:\(.*/\)\{0,1\}\(.*\)\.[^\.]*:\2:' \ - | grep -v main \ - | sort | uniq \ - >$@ - -.INTERMEDIATE: $(LIB).mllib -$(LIB).mllib: - echo Wasm >$@ - -_build/$(LIB).cmo: $(FILES) $(LIB).mlpack _tags Makefile - $(OCB) -quiet $(LIB).cmo - -_build/$(LIB).cmx: $(FILES) $(LIB).mlpack _tags Makefile - $(OCB) -quiet $(LIB).cmx - -_build/$(LIB).cma: $(FILES) $(LIB).mllib _tags Makefile - $(OCBA) -quiet $(LIB).cma - -_build/$(LIB).cmxa: $(FILES) $(LIB).mllib _tags Makefile - $(OCBA) -quiet $(LIB).cmxa - +.PHONY: smallint.exe +smallint.exe: + dune build $@ # Building JavaScript library -JSLIB_DIR = meta/jslib -JSLIB_FLAGS = -I $(JSLIB_DIR) -use-ocamlfind -pkg js_of_ocaml -pkg js_of_ocaml-ppx - -.INTERMEDIATE: $(JSLIB).byte -$(JSLIB).byte: $(JSLIB_DIR)/$(JSLIB).ml - $(OCBA) $(JSLIB_FLAGS) $@ - -$(JSLIB).js: $(JSLIB).byte - $(JSO) $< - -# Building Windows build file - -$(WINMAKE): clean - echo rem Auto-generated from Makefile! >$@ - echo set NAME=$(NAME) >>$@ - echo if \'%1\' neq \'\' set NAME=%1 >>$@ - $(OCB) main.byte \ - | grep -v ocamldep \ - | grep -v mkdir \ - | sed s:`which ocaml`:ocaml:g \ - | sed s:main/main.d.byte:%NAME%.exe: \ - >>$@ +$(JSLIB): $(BUILDDIR)/$(JSLIB) + cp $< $@ +$(BUILDDIR)/$(JSLIB): + dune build $(JSLIB) # Executing test suite @@ -142,78 +56,60 @@ TESTDIR = ../test/core TESTFILES = $(shell cd $(TESTDIR); ls *.wast; ls [a-z]*/*.wast) TESTS = $(TESTFILES:%.wast=%) -.PHONY: test debugtest partest dune-test +.PHONY: test partest dune-test test: $(OPT) smallint - $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) - ./smallint.native -debugtest: $(UNOPT) smallint - $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) - ./smallint.native + $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) + dune exec ./smallint.exe test/%: $(OPT) - $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast -debugtest/%: $(UNOPT) - $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast + $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast run/%: $(OPT) ./$(OPT) $(TESTDIR)/$*.wast -debug/%: $(UNOPT) - ./$(UNOPT) $(TESTDIR)/$*.wast -partest: $(TESTS:%=quiettest/%) +partest: $(TESTS:%=quiettest/%) @echo All tests passed. quiettest/%: $(OPT) @ ( \ - $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ + $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ rm $(@F).out \ ) || \ cat $(@F).out || rm $(@F).out || exit 1 smallinttest: smallint - @./smallint.native + dune exec ./smallint.exe dunetest: dune test +install: + dune build -p $(NAME) @install + dune install + +opam-release/%: + git tag opam-$* + git push --tags + rm -f opam-$*.zip + wget https://github.com/WebAssembly/spec/archive/opam-$*.zip + cp wasm.opam opam + echo "url {" >> opam + echo " src: \"https://github.com/WebAssembly/spec/archive/opam-$*.zip\"" >> opam + echo " checksum: \"md5=`md5 -q opam-$*.zip`\"" >> opam + echo "}" >> opam + rm opam-$*.zip + @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam # Miscellaneous targets .PHONY: clean -$(ZIP): $(WINMAKE) - git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD +$(ZIP): + git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD clean: - rm -rf _build/jslib $(LIB).mlpack _tags $(JSLIB).js - $(OCB) -clean - - -# Opam support - -.PHONY: check install uninstall + dune clean -check: - # Check that we can find all relevant libraries - # when using ocamlfind - ocamlfind query $(LIBS) - -install: _build/$(LIB).cmx _build/$(LIB).cmo - ocamlfind install $(LIB) meta/findlib/META _build/$(LIB).o \ - $(wildcard _build/$(LIB).cm*) \ - $(wildcard $(DIRS:%=%/*.mli)) - -uninstall: - ocamlfind remove $(LIB) - -opam-release/%: - git tag opam-$* - git push --tags - rm -f opam-$*.zip - wget https://github.com/WebAssembly/spec/archive/opam-$*.zip - cp meta/opam/opam . - sed -i ".tmp" s/@VERSION/$*/g opam - sed -i ".tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam - rm opam.tmp opam-$*.zip - @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam +distclean: clean + rm -f $(NAME) $(JSLIB) diff --git a/interpreter/README.md b/interpreter/README.md index fc2a1827a..1df7ff715 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -17,15 +17,14 @@ The text format defines modules in S-expression syntax. Moreover, it is generali You'll need OCaml 4.12 or higher. Instructions for installing a recent version of OCaml on multiple platforms are available [here](https://ocaml.org/docs/install.html). On most platforms, the recommended way is through [OPAM](https://ocaml.org/docs/install.html#OPAM). +You'll also need to install the dune build system. See the [installation instructions](https://github.com/ocaml/dune#installation-1). + Once you have OCaml, simply do ``` make ``` -You'll get an executable named `./wasm`. This is a byte code executable. If you want a (faster) native code executable, do -``` -make opt -``` +You'll get an executable named `./wasm`. To run the test suite, ``` make test @@ -34,12 +33,6 @@ To do everything: ``` make all ``` -Before committing changes, you should do -``` -make land -``` -That builds `all`, plus updates `winmake.bat`. - #### Building on Windows @@ -49,12 +42,6 @@ The instructions depend on how you [installed OCaml on Windows](https://ocaml.or 2. *Windows Subsystem for Linux* (WSL): You can build the interpreter using `make`, as described above. -3. *From source*: If you just want to build the interpreter and don't care about modifying it, you don't need to install the Cygwin core that comes with the installer. Just install OCaml itself and run -``` -winmake.bat -``` -in a Windows shell, which creates a program named `wasm`. Note that this will be a byte code executable only, i.e., somewhat slower. - In any way, in order to run the test suite you'll need to have Python installed. If you used Option 3, you can invoke the test runner `runtests.py` directly instead of doing it through `make`. diff --git a/interpreter/dune b/interpreter/dune index 48274aad9..c0e9c292f 100644 --- a/interpreter/dune +++ b/interpreter/dune @@ -1,16 +1,16 @@ (include_subdirs unqualified) (library - (name wasm) - ; The 'main' module shall not be part of the library, as it would start the + (public_name wasm) + ; The 'wasm' module shall not be part of the library, as it would start the ; Wasm REPL every time in all the dependencies. ; We exclude the 'wast' module as it is only used for the JS build. ; 'smallint' is a separate test module. - (modules :standard \ main smallint wast)) + (modules :standard \ main wasm smallint wast)) (executable - (name main) - (modules main) + (public_name wasm) + (modules wasm) (libraries wasm) (flags (-open Wasm))) @@ -22,6 +22,23 @@ (flags (-open Wasm))) +(executable + (name wast) + (modules wast) + (modes js) + (libraries js_of_ocaml wasm) + (preprocess (pps js_of_ocaml-ppx))) + +(rule + (targets wasm.ml) + (deps main/main.ml) + (action (copy main/main.ml wasm.ml))) + +(rule + (targets wast.js) + (deps wast.bc.js) + (action (copy wast.bc.js wast.js))) + (subdir text (rule @@ -42,10 +59,10 @@ (rule (alias runtest) (deps - ./main.exe + ./wasm.exe ./smallint.exe (source_tree ../test)) (action (progn - (run ../test/core/run.py --wasm ./main.exe) + (run ../test/core/run.py --wasm ./wasm.exe) (run ./smallint.exe)))) diff --git a/interpreter/dune-project b/interpreter/dune-project index c994249ac..0d15135d3 100644 --- a/interpreter/dune-project +++ b/interpreter/dune-project @@ -1 +1,20 @@ (lang dune 2.9) + +(name wasm) + +(generate_opam_files true) + +(license Apache-2.0) + +(source + (github WebAssembly/spec)) + +(authors "Andreas Rossberg = 4.12)))) diff --git a/interpreter/meta/jslib/wast.ml b/interpreter/jslib/wast.ml similarity index 99% rename from interpreter/meta/jslib/wast.ml rename to interpreter/jslib/wast.ml index 9af04f918..0ab4bd8fd 100644 --- a/interpreter/meta/jslib/wast.ml +++ b/interpreter/jslib/wast.ml @@ -1,6 +1,7 @@ (* Implements a wrapper library that allows the use of the reference * interpreter's encode/decode functionality in JavaScript. *) +open Wasm open Js_of_ocaml let _ = diff --git a/interpreter/meta/findlib/META b/interpreter/meta/findlib/META deleted file mode 100644 index 2c1d96dd0..000000000 --- a/interpreter/meta/findlib/META +++ /dev/null @@ -1,4 +0,0 @@ -description = "A library for writing/reading/running WebAssembly binaries" -requires = "bigarray,str" -archive(byte) = "wasm.cmo" -archive(native) = "wasm.cmx" diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam deleted file mode 100644 index 845fe675e..000000000 --- a/interpreter/meta/opam/opam +++ /dev/null @@ -1,23 +0,0 @@ -opam-version: "2.0" -maintainer: "Andreas Rossberg " -authors: "Andreas Rossberg " -homepage: "https://github.com/WebAssembly/spec" -bug-reports: "https://github.com/WebAssembly/spec/issues" -license: "Apache-2.0" -dev-repo: "git+https://github.com/WebAssembly/spec.git" -build: [ - [make "-C" "interpreter" "opt" "unopt"] -] -install: [make "-C" "interpreter" "install"] -depends: [ - "ocaml" {>= "4.12.0"} - "ocamlfind" {build} - "ocamlbuild" {build} -] -conflicts: ["ocaml-option-bytecode-only"] # uses ocamlopt unconconditionally -synopsis: - "Library to read and write WebAssembly (Wasm) files and manipulate their AST" -url { - src: "https://github.com/WebAssembly/spec/archive/opam-@VERSION.zip" - checksum: "md5=@MD5" -} diff --git a/interpreter/wasm.opam b/interpreter/wasm.opam new file mode 100644 index 000000000..5d5984106 --- /dev/null +++ b/interpreter/wasm.opam @@ -0,0 +1,32 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: + "Library to read and write WebAssembly (Wasm) files and manipulate their AST" +maintainer: ["Andreas Rossberg = "2.9"} + "ocaml" {>= "4.12"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "--promote-install-files=false" + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] + ["dune" "install" "-p" name "--create-install-files" name] +] +dev-repo: "git+https://github.com/WebAssembly/spec.git" diff --git a/interpreter/winmake.bat b/interpreter/winmake.bat deleted file mode 100644 index 6ff7e8caa..000000000 --- a/interpreter/winmake.bat +++ /dev/null @@ -1,75 +0,0 @@ -rem Auto-generated from Makefile! -set NAME=wasm -if '%1' neq '' set NAME=%1 -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/numeric_error.cmo exec/numeric_error.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/int.cmo exec/int.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/lib.cmi util/lib.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32.cmo exec/i32.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/float.cmo exec/float.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/types.cmo syntax/types.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32.cmo exec/f32.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64.cmo exec/f64.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64.cmo exec/i64.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/values.cmo syntax/values.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/memory.cmi runtime/memory.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/source.cmi util/source.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/ast.cmo syntax/ast.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/func.cmi runtime/func.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/global.cmi runtime/global.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/table.cmi runtime/table.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/instance.cmo runtime/instance.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval.cmi exec/eval.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/utf8.cmi binary/utf8.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I host -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I valid -o host/env.cmo host/env.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o main/flags.cmo main/flags.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/import.cmi script/import.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/run.cmi script/run.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I host -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I valid -o host/spectest.cmo host/spectest.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o main/main.cmo main/main.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/error.cmi util/error.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/script.cmo script/script.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/decode.cmi binary/decode.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/encode.cmi binary/encode.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/js.cmi script/js.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parse.cmi text/parse.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/print.cmi text/print.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I valid -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -o valid/valid.cmi valid/valid.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/import.cmo script/import.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/run.cmo script/run.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/utf8.cmo binary/utf8.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval_numeric.cmi exec/eval_numeric.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64_convert.cmi exec/i64_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval.cmo exec/eval.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/func.cmo runtime/func.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/source.cmo util/source.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32_convert.cmi exec/f32_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64_convert.cmi exec/f64_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32_convert.cmi exec/i32_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/error.cmo util/error.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval_numeric.cmo exec/eval_numeric.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/global.cmo runtime/global.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64_convert.cmo exec/i64_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/lib.cmo util/lib.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/memory.cmo runtime/memory.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/table.cmo runtime/table.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32_convert.cmo exec/f32_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64_convert.cmo exec/f64_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32_convert.cmo exec/i32_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/operators.cmo syntax/operators.ml -ocamlyacc text/parser.mly -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parser.cmi text/parser.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/lexer.cmi text/lexer.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/sexpr.cmi util/sexpr.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/arrange.cmi text/arrange.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/decode.cmo binary/decode.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/encode.cmo binary/encode.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/js.cmo script/js.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parse.cmo text/parse.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/print.cmo text/print.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I valid -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -o valid/valid.cmo valid/valid.ml -ocamllex.opt -q text/lexer.mll -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/lexer.cmo text/lexer.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parser.cmo text/parser.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/arrange.cmo text/arrange.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/sexpr.cmo util/sexpr.ml -ocamlc.opt bigarray.cma -I util -I binary -I exec -I syntax -I runtime -I host -I main -I script -I text -I valid util/lib.cmo binary/utf8.cmo exec/float.cmo exec/f32.cmo exec/f64.cmo exec/numeric_error.cmo exec/int.cmo exec/i32.cmo exec/i64.cmo exec/i32_convert.cmo exec/f32_convert.cmo exec/i64_convert.cmo exec/f64_convert.cmo syntax/types.cmo syntax/values.cmo runtime/memory.cmo util/source.cmo syntax/ast.cmo exec/eval_numeric.cmo runtime/func.cmo runtime/global.cmo runtime/table.cmo runtime/instance.cmo util/error.cmo exec/eval.cmo host/env.cmo host/spectest.cmo main/flags.cmo script/import.cmo binary/encode.cmo syntax/operators.cmo binary/decode.cmo script/script.cmo text/parser.cmo text/lexer.cmo text/parse.cmo script/js.cmo util/sexpr.cmo text/arrange.cmo text/print.cmo valid/valid.cmo script/run.cmo main/main.cmo -o main/main.byte From b78e1d0750478d9a7edd0f2380d3a323d54c8835 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 1 Sep 2023 09:43:33 +0200 Subject: [PATCH 11/33] Fix and clean up Makefile --- interpreter/Makefile | 113 +++++++++++--------- interpreter/dune | 5 - interpreter/{tests => unittest}/smallint.ml | 0 3 files changed, 62 insertions(+), 56 deletions(-) rename interpreter/{tests => unittest}/smallint.ml (100%) diff --git a/interpreter/Makefile b/interpreter/Makefile index d67882b29..fe6accd93 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -1,6 +1,6 @@ # This Makefile uses dune but does not rely on ocamlfind or the Opam # package manager to build. However, Opam package management is available -# optionally through the check/install/uninstall targets. +# optionally through the install target. # # The $(JSLIB).js target requires Js_of_ocaml (using ocamlfind). # @@ -9,80 +9,90 @@ # Configuration -NAME = wasm -OPT = $(NAME).exe -ZIP = $(NAME).zip +NAME = wasm +LIB = $(NAME) JSLIB = wast.js +ZIP = $(NAME).zip -BUILDDIR = _build/default +BUILDDIR = _build/default JS = # set to JS shell command to run JS tests, empty to skip # Main targets -.PHONY: default opt jslib all zip smallint +.PHONY: default all ci jslib zip + +default: $(NAME) +all: default test +ci: all jslib zip -default: $(OPT) jslib: $(JSLIB) -all: $(OPT) test zip: $(ZIP) -smallint: smallint.exe -ci: all jslib -# Building executable -.PHONY: $(NAME).exe -$(NAME).exe: - rm -f $(NAME) - dune build $@ - cp $(BUILDDIR)/$(OPT) $(NAME) -.PHONY: smallint.exe -smallint.exe: - dune build $@ +# Building + +$(NAME): + rm -f $@ + dune build $@.exe + ln $(BUILDDIR)/$@.exe $@ + +$(JSLIB): + rm -f $@ + dune build $(@:%.js=%.bc.js) + ln $(BUILDDIR)/$(@:%.js=%.bc.js) $@ + + +# Unit tests + +UNITTESTDIR = unittest +UNITTESTFILES = $(shell cd $(UNITTESTDIR); ls *.ml) +UNITTESTS = $(UNITTESTFILES:%.ml=%) -# Building JavaScript library +.PHONY: unittest -$(JSLIB): $(BUILDDIR)/$(JSLIB) - cp $< $@ +unittest: $(UNITTESTS:%=unittest/%) -$(BUILDDIR)/$(JSLIB): - dune build $(JSLIB) +unittest/%: + dune build $(@F).exe + dune exec ./$(@F).exe -# Executing test suite + +# Test suite TESTDIR = ../test/core -# Skip _output directory, since that's a tmp directory, and list all other wast files. TESTFILES = $(shell cd $(TESTDIR); ls *.wast; ls [a-z]*/*.wast) TESTS = $(TESTFILES:%.wast=%) -.PHONY: test partest dune-test +.PHONY: test partest quiettest + +test: $(NAME) unittest + $(TESTDIR)/run.py --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) -test: $(OPT) smallint - $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) - dune exec ./smallint.exe +test/%: $(NAME) + $(TESTDIR)/run.py --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast -test/%: $(OPT) - $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast +run/%: $(NAME) + ./$(NAME) $(TESTDIR)/$*.wast -run/%: $(OPT) - ./$(OPT) $(TESTDIR)/$*.wast +partest: $(NAME) + make -j10 quiettest -partest: $(TESTS:%=quiettest/%) - @echo All tests passed. +quiettest: $(TESTS:%=quiettest/%) + @echo All tests passed. -quiettest/%: $(OPT) - @ ( \ - $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ - rm $(@F).out \ - ) || \ - cat $(@F).out || rm $(@F).out || exit 1 +quiettest/%: $(NAME) + @ ( \ + $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ + rm $(@F).out \ + ) || \ + cat $(@F).out || rm $(@F).out || exit 1 -smallinttest: smallint - dune exec ./smallint.exe -dunetest: - dune test +# Packaging + +.PHONY: install install: dune build -p $(NAME) @install @@ -101,15 +111,16 @@ opam-release/%: rm opam-$*.zip @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam -# Miscellaneous targets - -.PHONY: clean - $(ZIP): git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD + +# Cleanup + +.PHONY: clean distclean + clean: dune clean distclean: clean - rm -f $(NAME) $(JSLIB) + rm -f $(NAME) $(JSLIB) $(ZIP) diff --git a/interpreter/dune b/interpreter/dune index c0e9c292f..9a853921d 100644 --- a/interpreter/dune +++ b/interpreter/dune @@ -34,11 +34,6 @@ (deps main/main.ml) (action (copy main/main.ml wasm.ml))) -(rule - (targets wast.js) - (deps wast.bc.js) - (action (copy wast.bc.js wast.js))) - (subdir text (rule diff --git a/interpreter/tests/smallint.ml b/interpreter/unittest/smallint.ml similarity index 100% rename from interpreter/tests/smallint.ml rename to interpreter/unittest/smallint.ml From 6ef660e9897a968c044429409107acb4a1c97a08 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 1 Sep 2023 09:49:14 +0200 Subject: [PATCH 12/33] Make partest the default --- interpreter/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index fe6accd93..9d345cb46 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -24,7 +24,7 @@ JS = # set to JS shell command to run JS tests, empty to skip .PHONY: default all ci jslib zip default: $(NAME) -all: default test +all: default partest ci: all jslib zip jslib: $(JSLIB) @@ -87,7 +87,7 @@ quiettest/%: $(NAME) $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ rm $(@F).out \ ) || \ - cat $(@F).out || rm $(@F).out || exit 1 + (cat $(@F).out && rm $(@F).out && exit 1) # Packaging From 5c96167c22c1ba2fdf032df9877a1fcc3ff2e4a4 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Wed, 6 Sep 2023 08:02:38 -0700 Subject: [PATCH 13/33] [spec] Clarify that elements are given as expressions (#1676) --- document/core/syntax/instructions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index e22c42002..ddb51d7ee 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -707,7 +707,7 @@ the callee is dynamically checked against the :ref:`function type ` bodies, initialization values for :ref:`globals `, and offsets of :ref:`element ` or :ref:`data ` segments are given as expressions, which are sequences of :ref:`instructions ` terminated by an |END| marker. +:ref:`Function ` bodies, initialization values for :ref:`globals `, elements and offsets of :ref:`element ` segments, and offsets of :ref:`data ` segments are given as expressions, which are sequences of :ref:`instructions ` terminated by an |END| marker. .. math:: \begin{array}{llll} From 5cf98bcf3b7609d2154f7f65afe8fd25774c54e6 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 8 Sep 2023 20:00:20 +0900 Subject: [PATCH 14/33] [test] Fix typos (#1678) --- test/core/unreachable.wast | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/unreachable.wast b/test/core/unreachable.wast index 3074847a3..19f661be1 100644 --- a/test/core/unreachable.wast +++ b/test/core/unreachable.wast @@ -6,8 +6,8 @@ (func $dummy3 (param i32 i32 i32)) (func (export "type-i32") (result i32) (unreachable)) - (func (export "type-i64") (result i32) (unreachable)) - (func (export "type-f32") (result f64) (unreachable)) + (func (export "type-i64") (result i64) (unreachable)) + (func (export "type-f32") (result f32) (unreachable)) (func (export "type-f64") (result f64) (unreachable)) (func (export "as-func-first") (result i32) From cf73a6d58eb211f32d6cc66ba5345b317c1883b2 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Wed, 20 Sep 2023 08:02:43 -0700 Subject: [PATCH 15/33] [test] text format: drop support for some pre-standard keywords (#1680) --- test/core/obsolete-keywords.wast | 82 ++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 test/core/obsolete-keywords.wast diff --git a/test/core/obsolete-keywords.wast b/test/core/obsolete-keywords.wast new file mode 100644 index 000000000..a90eb96d2 --- /dev/null +++ b/test/core/obsolete-keywords.wast @@ -0,0 +1,82 @@ +;; Renamed in https://github.com/WebAssembly/spec/pull/720 +(assert_malformed + (module quote + "(memory 1)" + "(func (drop (current_memory)))" + ) + "unknown operator current_memory" +) + +(assert_malformed + (module quote + "(memory 1)" + "(func (drop (grow_memory (i32.const 0))))" + ) + "unknown operator grow_memory" +) + +;; Renamed in https://github.com/WebAssembly/spec/pull/926 +(assert_malformed + (module quote + "(func (local $i i32) (drop (get_local $i)))" + ) + "unknown operator get_local" +) + +(assert_malformed + (module quote + "(func (local $i i32) (set_local $i (i32.const 0)))" + ) + "unknown operator set_local" +) + +(assert_malformed + (module quote + "(func (local $i i32) (drop (tee_local $i (i32.const 0))))" + ) + "unknown operator tee_local" +) + +(assert_malformed + (module quote + "(global $g anyfunc (ref.null func))" + ) + "unknown operator anyfunc" +) + +(assert_malformed + (module quote + "(global $g i32 (i32.const 0))" + "(func (drop (get_global $g)))" + ) + "unknown operator get_global" +) + +(assert_malformed + (module quote + "(global $g (mut i32) (i32.const 0))" + "(func (set_global $g (i32.const 0)))" + ) + "unknown operator set_global" +) + +(assert_malformed + (module quote + "(func (drop (i32.wrap/i64 (i64.const 0))))" + ) + "unknown operator i32.wrap/i64" +) + +(assert_malformed + (module quote + "(func (drop (i32.trunc_s:sat/f32 (f32.const 0))))" + ) + "unknown operator i32.trunc_s:sat/f32" +) + +(assert_malformed + (module quote + "(func (drop (f32x4.convert_s/i32x4 (v128.const i64x2 0 0))))" + ) + "unknown operator f32x4.convert_s/i32x4" +) From 0c5b9c00e41e87e60bddc70d25add33594cac7d1 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 20 Sep 2023 18:28:06 -0700 Subject: [PATCH 16/33] [test] Test that atypical folded if conditions are parsed correctly (#1682) Check that the condition must be a sequence of folded (as opposed to unfolded) instructions, but also check that having zero or multiple folded instructions is allowed. --- test/core/if.wast | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/core/if.wast b/test/core/if.wast index 1cbb617a7..2ea45f6fa 100644 --- a/test/core/if.wast +++ b/test/core/if.wast @@ -524,6 +524,14 @@ ) (drop) (drop) (drop) ) + + ;; Atypical folded condition syntax + + (func (export "atypical-condition") + i32.const 0 + (if (then) (else)) + (if (i32.const 1) (i32.eqz) (then) (else)) + ) ) (assert_return (invoke "empty" (i32.const 0))) @@ -722,6 +730,8 @@ (assert_return (invoke "type-use")) +(assert_return (invoke "atypical-condition")) + (assert_malformed (module quote "(type $sig (func (param i32) (result i32)))" @@ -1547,4 +1557,8 @@ (assert_malformed (module quote "(func i32.const 0 if $a else $l end $l)") "mismatching label" +) +(assert_malformed + (module quote "(func (if i32.const 0 (then) (else)))") + "unexpected token" ) \ No newline at end of file From b174a7d544fb1183a6fad8c10078604978339bd5 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 21 Sep 2023 14:44:11 +0200 Subject: [PATCH 17/33] [interpreter] Run unittests with partest --- interpreter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 9d345cb46..f7ecc482a 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -76,7 +76,7 @@ test/%: $(NAME) run/%: $(NAME) ./$(NAME) $(TESTDIR)/$*.wast -partest: $(NAME) +partest: $(NAME) unittest make -j10 quiettest quiettest: $(TESTS:%=quiettest/%) From bfb21e96f99820e0cfb0c41a264bd0d42795bfe2 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 21 Sep 2023 18:06:15 -0700 Subject: [PATCH 18/33] [interpreter] Update Makefile to ignore output of `cd` (#1683) The interpreter Makefile captures the output of cding into the unittest directory and listing the unittest files it contains. Under some circumstances, the `cd` command will print the new current directory, and that output was incorrectly being interpreted as the path to a unittest, causing the build to fail. Fix this problem by redirecting the output of cd, if any, to /dev/null. Fixes #1681. --- interpreter/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index f7ecc482a..688bbc1aa 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -47,7 +47,7 @@ $(JSLIB): # Unit tests UNITTESTDIR = unittest -UNITTESTFILES = $(shell cd $(UNITTESTDIR); ls *.ml) +UNITTESTFILES = $(shell cd $(UNITTESTDIR) > /dev/null; ls *.ml) UNITTESTS = $(UNITTESTFILES:%.ml=%) .PHONY: unittest @@ -62,7 +62,7 @@ unittest/%: # Test suite TESTDIR = ../test/core -TESTFILES = $(shell cd $(TESTDIR); ls *.wast; ls [a-z]*/*.wast) +TESTFILES = $(shell cd $(TESTDIR) > /dev/null; ls *.wast; ls [a-z]*/*.wast) TESTS = $(TESTFILES:%.wast=%) .PHONY: test partest quiettest From 404c81c3bfff7dd020b5ccc764da1426aefb75a4 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 25 Sep 2023 15:04:10 +0200 Subject: [PATCH 19/33] [interpreter] Fix Makefile targets --- interpreter/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interpreter/Makefile b/interpreter/Makefile index 688bbc1aa..5939f838e 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -33,6 +33,8 @@ zip: $(ZIP) # Building +.PHONY: $(NAME) $(JSLIB) + $(NAME): rm -f $@ dune build $@.exe From ac2aeb96237e4dbc5800f8df31c366b38666b142 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 25 Sep 2023 16:00:07 +0200 Subject: [PATCH 20/33] [test] Merge token and tokens tests --- test/core/token.wast | 276 ++++++++++++++++++++++++++++++++++++++++++ test/core/tokens.wast | 274 ----------------------------------------- 2 files changed, 276 insertions(+), 274 deletions(-) delete mode 100644 test/core/tokens.wast diff --git a/test/core/token.wast b/test/core/token.wast index 1dcd32e7f..624bdca6d 100644 --- a/test/core/token.wast +++ b/test/core/token.wast @@ -8,3 +8,279 @@ (module quote "(func br 0drop)") "unknown operator" ) + + +;; Tokens can be delimited by parentheses + +(module + (func(nop)) +) +(module + (func (nop)nop) +) +(module + (func nop(nop)) +) +(module + (func(nop)(nop)) +) +(module + (func $f(nop)) +) +(module + (func br 0(nop)) +) +(module + (table 1 funcref) + (func) + (elem (i32.const 0)0) +) +(module + (table 1 funcref) + (func $f) + (elem (i32.const 0)$f) +) +(module + (memory 1) + (data (i32.const 0)"a") +) +(module + (import "spectest" "print"(func)) +) + + +;; Tokens can be delimited by comments + +(module + (func;;bla + ) +) +(module + (func (nop);;bla + ) +) +(module + (func nop;;bla + ) +) +(module + (func $f;;bla + ) +) +(module + (func br 0;;bla + ) +) +(module + (data "a";;bla + ) +) + + +;; Space required between symbols and non-parenthesis tokens + +(module + (func (block $l (i32.const 0) (br_table 0 $l))) +) +(assert_malformed + (module quote + "(func (block $l (i32.const 0) (br_table 0$l)))" + ) + "unknown operator" +) + +(module + (func (block $l (i32.const 0) (br_table $l 0))) +) +(assert_malformed + (module quote + "(func (block $l (i32.const 0) (br_table $l0)))" + ) + "unknown label" +) + +(module + (func (block $l (i32.const 0) (br_table $l $l))) +) +(assert_malformed + (module quote + "(func (block $l (i32.const 0) (br_table $l$l)))" + ) + "unknown label" +) + +(module + (func (block $l0 (i32.const 0) (br_table $l0))) +) +(module + (func (block $l$l (i32.const 0) (br_table $l$l))) +) + + +;; Space required between strings and non-parenthesis tokens + +(module + (data "a") +) +(assert_malformed + (module quote + "(data\"a\")" + ) + "unknown operator" +) + +(module + (data $l "a") +) +(assert_malformed + (module quote + "(data $l\"a\")" + ) + "unknown operator" +) + +(module + (data $l " a") +) +(assert_malformed + (module quote + "(data $l\" a\")" + ) + "unknown operator" +) + +(module + (data $l "a ") +) +(assert_malformed + (module quote + "(data $l\"a \")" + ) + "unknown operator" +) + +(module + (data $l "a " "b") +) +(assert_malformed + (module quote + "(data $l\"a \"\"b\")" + ) + "unknown operator" +) + +(module + (data $l "") +) +(assert_malformed + (module quote + "(data $l\"\")" + ) + "unknown operator" +) + +(module + (data $l " ") +) +(assert_malformed + (module quote + "(data $l\" \")" + ) + "unknown operator" +) + +(module + (data $l " ") +) +(assert_malformed + (module quote + "(data $l\" \")" + ) + "unknown operator" +) + +(module + (data "a" "b") +) +(assert_malformed + (module quote + "(data \"a\"\"b\")" + ) + "unknown operator" +) + +(module + (data "a" " b") +) +(assert_malformed + (module quote + "(data \"a\"\" b\")" + ) + "unknown operator" +) + +(module + (data "a " "b") +) +(assert_malformed + (module quote + "(data \"a \"\"b\")" + ) + "unknown operator" +) + +(module + (data "" "") +) +(assert_malformed + (module quote + "(data \"\"\"\")" + ) + "unknown operator" +) + +(module + (data "" " ") +) +(assert_malformed + (module quote + "(data \"\"\" \")" + ) + "unknown operator" +) + +(module + (data " " "") +) +(assert_malformed + (module quote + "(data \" \"\"\")" + ) + "unknown operator" +) + + +(assert_malformed + (module quote + "(func \"a\"x)" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(func \"a\"0)" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(func 0\"a\")" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(func \"a\"$x)" + ) + "unknown operator" +) diff --git a/test/core/tokens.wast b/test/core/tokens.wast deleted file mode 100644 index 4e785154e..000000000 --- a/test/core/tokens.wast +++ /dev/null @@ -1,274 +0,0 @@ -;; Tokens can be delimited by parentheses - -(module - (func(nop)) -) -(module - (func (nop)nop) -) -(module - (func nop(nop)) -) -(module - (func(nop)(nop)) -) -(module - (func $f(nop)) -) -(module - (func br 0(nop)) -) -(module - (table 1 funcref) - (func) - (elem (i32.const 0)0) -) -(module - (table 1 funcref) - (func $f) - (elem (i32.const 0)$f) -) -(module - (memory 1) - (data (i32.const 0)"a") -) -(module - (import "spectest" "print"(func)) -) - - -;; Tokens can be delimited by comments - -(module - (func;;bla - ) -) -(module - (func (nop);;bla - ) -) -(module - (func nop;;bla - ) -) -(module - (func $f;;bla - ) -) -(module - (func br 0;;bla - ) -) -(module - (data "a";;bla - ) -) - - -;; Space required between symbols and non-parenthesis tokens - -(module - (func (block $l (i32.const 0) (br_table 0 $l))) -) -(assert_malformed - (module quote - "(func (block $l (i32.const 0) (br_table 0$l)))" - ) - "unknown operator" -) - -(module - (func (block $l (i32.const 0) (br_table $l 0))) -) -(assert_malformed - (module quote - "(func (block $l (i32.const 0) (br_table $l0)))" - ) - "unknown label" -) - -(module - (func (block $l (i32.const 0) (br_table $l $l))) -) -(assert_malformed - (module quote - "(func (block $l (i32.const 0) (br_table $l$l)))" - ) - "unknown label" -) - -(module - (func (block $l0 (i32.const 0) (br_table $l0))) -) -(module - (func (block $l$l (i32.const 0) (br_table $l$l))) -) - - -;; Space required between strings and non-parenthesis tokens - -(module - (data "a") -) -(assert_malformed - (module quote - "(data\"a\")" - ) - "unknown operator" -) - -(module - (data $l "a") -) -(assert_malformed - (module quote - "(data $l\"a\")" - ) - "unknown operator" -) - -(module - (data $l " a") -) -(assert_malformed - (module quote - "(data $l\" a\")" - ) - "unknown operator" -) - -(module - (data $l "a ") -) -(assert_malformed - (module quote - "(data $l\"a \")" - ) - "unknown operator" -) - -(module - (data $l "a " "b") -) -(assert_malformed - (module quote - "(data $l\"a \"\"b\")" - ) - "unknown operator" -) - -(module - (data $l "") -) -(assert_malformed - (module quote - "(data $l\"\")" - ) - "unknown operator" -) - -(module - (data $l " ") -) -(assert_malformed - (module quote - "(data $l\" \")" - ) - "unknown operator" -) - -(module - (data $l " ") -) -(assert_malformed - (module quote - "(data $l\" \")" - ) - "unknown operator" -) - -(module - (data "a" "b") -) -(assert_malformed - (module quote - "(data \"a\"\"b\")" - ) - "unknown operator" -) - -(module - (data "a" " b") -) -(assert_malformed - (module quote - "(data \"a\"\" b\")" - ) - "unknown operator" -) - -(module - (data "a " "b") -) -(assert_malformed - (module quote - "(data \"a \"\"b\")" - ) - "unknown operator" -) - -(module - (data "" "") -) -(assert_malformed - (module quote - "(data \"\"\"\")" - ) - "unknown operator" -) - -(module - (data "" " ") -) -(assert_malformed - (module quote - "(data \"\"\" \")" - ) - "unknown operator" -) - -(module - (data " " "") -) -(assert_malformed - (module quote - "(data \" \"\"\")" - ) - "unknown operator" -) - - -(assert_malformed - (module quote - "(func \"a\"x)" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(func \"a\"0)" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(func 0\"a\")" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(func \"a\"$x)" - ) - "unknown operator" -) From dce0593d391867b6d34ddc744fa9efa741470cd9 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 25 Sep 2023 16:01:04 +0200 Subject: [PATCH 21/33] [test] Make runner robust wrt parallel races --- test/core/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/run.py b/test/core/run.py index 27c069436..0b98e4e3d 100755 --- a/test/core/run.py +++ b/test/core/run.py @@ -112,7 +112,7 @@ def _runTestFile(self, inputPath): if __name__ == "__main__": if not os.path.exists(outputDir): - os.makedirs(outputDir) + os.makedirs(outputDir, exists_ok=True) for fileName in inputFiles: testName = 'test ' + os.path.basename(fileName) setattr(RunTests, testName, lambda self, file=fileName: self._runTestFile(file)) From ea7237b9e69b35018ea1fc0d47d32daa4820cbbc Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 25 Sep 2023 07:03:56 -0700 Subject: [PATCH 22/33] [interpreter] Update {memory,table}.copy to match spec text (#1666) Change the interpreter implementation of backward copying in the evaluation of memory.copy and table.copy to match the implementation given in the spec. This does not change any behavior. --- interpreter/exec/eval.ml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 18ff7150d..90221c4cd 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -286,15 +286,16 @@ let rec step (c : config) : config = Plain (TableCopy (x, y)); ] else (* d > s *) + let n' = I32.sub n 1l in vs', List.map (at e.at) [ - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); - Plain (TableCopy (x, y)); - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); + Plain (Const (I32 (I32.add d n') @@ e.at)); + Plain (Const (I32 (I32.add s n') @@ e.at)); Plain (TableGet y); Plain (TableSet x); + Plain (Const (I32 d @@ e.at)); + Plain (Const (I32 s @@ e.at)); + Plain (Const (I32 n' @@ e.at)); + Plain (TableCopy (x, y)); ] | TableInit (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> @@ -447,17 +448,18 @@ let rec step (c : config) : config = Plain (MemoryCopy); ] else (* d > s *) + let n' = I32.sub n 1l in vs', List.map (at e.at) [ - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); - Plain (MemoryCopy); - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); + Plain (Const (I32 (I32.add d n') @@ e.at)); + Plain (Const (I32 (I32.add s n') @@ e.at)); Plain (Load {ty = I32Type; align = 0; offset = 0l; pack = Some (Pack8, ZX)}); Plain (Store {ty = I32Type; align = 0; offset = 0l; pack = Some Pack8}); + Plain (Const (I32 d @@ e.at)); + Plain (Const (I32 s @@ e.at)); + Plain (Const (I32 n' @@ e.at)); + Plain (MemoryCopy); ] | MemoryInit x, Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> From 105567f51466df267becb563b78726815fb0157e Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 25 Sep 2023 16:11:13 +0200 Subject: [PATCH 23/33] [test] Fix typo in runner --- test/core/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/run.py b/test/core/run.py index 0b98e4e3d..cbdb25654 100755 --- a/test/core/run.py +++ b/test/core/run.py @@ -112,7 +112,7 @@ def _runTestFile(self, inputPath): if __name__ == "__main__": if not os.path.exists(outputDir): - os.makedirs(outputDir, exists_ok=True) + os.makedirs(outputDir, exist_ok=True) for fileName in inputFiles: testName = 'test ' + os.path.basename(fileName) setattr(RunTests, testName, lambda self, file=fileName: self._runTestFile(file)) From 0206eb30d6b34122906ffa2c9b6dc61092a2e6c7 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 27 Jul 2023 09:31:39 +0200 Subject: [PATCH 24/33] [js-api] Editorial: fix some references to 'agent' --- document/js-api/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index e31e47abd..198cbe440 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -154,6 +154,7 @@ spec:ecma-262; type:exception; for:ECMAScript; text:Error spec:ecmascript; type:exception; for:ECMAScript; text:TypeError spec:ecmascript; type:exception; for:ECMAScript; text:RangeError spec:ecmascript; type:interface; for:ECMAScript; text:ArrayBuffer +spec:ecmascript; type:dfn; text:agent spec:webidl; type:dfn; text:resolve @@ -845,7 +846,7 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
To create a global object from a [=global address=] |globaladdr|, perform the following steps: - 1. Let |map| be the current [=agent=]'s associated [=Global object cache=]. + 1. Let |map| be the [=surrounding agent=]'s associated [=Global object cache=]. 1. If |map|[|globaladdr|] [=map/exists=], 1. Return |map|[|globaladdr|]. 1. Let |global| be a [=/new=] {{Global}}. From 5143ee37c5c13d54a7cb02bfb5cf2ff88c85dad4 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 27 Jul 2023 09:32:05 +0200 Subject: [PATCH 25/33] [js-api] Editorial: replace reference to removed IterableToList abstract operation --- document/js-api/index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 198cbe440..9345955c5 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -1013,7 +1013,7 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not 1. Otherwise, 1. Let |method| be [=?=] [$GetMethod$](|ret|, {{@@iterator}}). 1. If |method| is undefined, [=throw=] a {{TypeError}}. - 1. Let |values| be [=?=] [$IterableToList$](|ret|, |method|). + 1. Let |values| be [=?=] [$IteratorToList$]([=?=] [$GetIteratorFromMethod$](|ret|, |method|)). 1. Let |wasmValues| be a new, empty [=list=]. 1. If |values|'s [=list/size=] is not |resultsSize|, throw a {{TypeError}} exception. 1. For each |value| and |resultType| in |values| and |results|, paired linearly, From 45c71475739cf6fcf36f2deb51f7088ae8dc7113 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 27 Jul 2023 09:32:31 +0200 Subject: [PATCH 26/33] [js-api] Editorial: drop unused algorithm This became unused in #745. --- document/js-api/index.bs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 9345955c5..168f54800 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -433,16 +433,6 @@ The verification of WebAssembly type requirements is deferred to the 1. Return |promise|.
-
- To synchronously instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: - 1. Let |module| be |moduleObject|.\[[Module]]. - 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. - 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. - 1. Let |instanceObject| be a [=/new=] {{Instance}}. - 1. [=initialize an instance object|Initialize=] |instanceObject| from |module| and |instance|. - 1. Return |instanceObject|. -
-
To instantiate a promise of a module |promiseOfModule| with imports |importObject|, perform the following steps: From 0ed695b9c4f7d6329afd732108e62916d2e64e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20J=C3=A4genstedt?= Date: Fri, 6 Oct 2023 16:11:04 +0200 Subject: [PATCH 27/33] [ci] Don't install ocamlbuild (#1686) --- .github/workflows/ci-interpreter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-interpreter.yml b/.github/workflows/ci-interpreter.yml index 6edfa0c46..0236c4939 100644 --- a/.github/workflows/ci-interpreter.yml +++ b/.github/workflows/ci-interpreter.yml @@ -23,7 +23,7 @@ jobs: with: ocaml-compiler: 4.12.x - name: Setup OCaml tools - run: opam install --yes ocamlbuild.0.14.0 ocamlfind.1.9.5 js_of_ocaml.4.0.0 js_of_ocaml-ppx.4.0.0 + run: opam install --yes ocamlfind.1.9.5 js_of_ocaml.4.0.0 js_of_ocaml-ppx.4.0.0 - name: Setup Node.js uses: actions/setup-node@v2 with: From 84158a765ce284e978814d811424811485c043e2 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Sat, 14 Oct 2023 11:36:38 +0200 Subject: [PATCH 28/33] [spec] Fix typo --- document/core/appendix/properties.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/appendix/properties.rst b/document/core/appendix/properties.rst index 3804dd4aa..c42a85a54 100644 --- a/document/core/appendix/properties.rst +++ b/document/core/appendix/properties.rst @@ -665,9 +665,9 @@ a store state :math:`S'` extends state :math:`S`, written :math:`S \extendsto S' * 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:`element instance ` :math:`\eleminst_i` in the original :math:`S.\SELEMS`, the new element 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. +* For each :ref:`data instance ` :math:`\datainst_i` in the original :math:`S.\SDATAS`, the new data instance must be an :ref:`extension ` of the old. .. math:: \frac{ From be1f56354b251ae15b6ac4220c5ea0f0a5f894f9 Mon Sep 17 00:00:00 2001 From: RIRU <92210252+RI5255@users.noreply.github.com> Date: Mon, 16 Oct 2023 23:59:12 +0900 Subject: [PATCH 29/33] [spec] Pop dummy frame after Invocation (#1691) --- document/core/exec/modules.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/document/core/exec/modules.rst b/document/core/exec/modules.rst index ad485c361..cdb20d03c 100644 --- a/document/core/exec/modules.rst +++ b/document/core/exec/modules.rst @@ -798,6 +798,10 @@ Once the function has returned, the following steps are executed: 2. Pop :math:`\val_{\F{res}}^m` from the stack. +3. Assert: due to :ref:`validation `, the frame :math:`F` is now on the top of the stack. + +4. Pop the frame :math:`F` from the stack. + The values :math:`\val_{\F{res}}^m` are returned as the results of the invocation. .. math:: From b39baf7795a8a6d969ae713ce2088ef0fb8c8ebe Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 24 Oct 2023 18:11:01 +0200 Subject: [PATCH 30/33] [spec] Fix definition of iextend (#1696) --- document/core/exec/numerics.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index f9eae6b9d..85d3dbd00 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -715,11 +715,13 @@ The integer result of predicates -- i.e., :ref:`tests ` and :ref: :math:`\iextendMs_N(i)` ....................... -* Return :math:`\extends_{M,N}(i)`. +* Let :math:`j` be the result of computing :math:`\wrap_{N,M}(i)`. + +* Return :math:`\extends_{M,N}(j)`. .. math:: \begin{array}{lll@{\qquad}l} - \iextendMs_{N}(i) &=& \extends_{M,N}(i) \\ + \iextendMs_{N}(i) &=& \extends_{M,N}(\wrap_{N,M}(i)) \\ \end{array} From 43d405f5301adefb823b443c6fb9bb6093b1e1a7 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 25 Oct 2023 21:55:07 +0200 Subject: [PATCH 31/33] [spec/interpreter/test] Align definition of newline with Unicode recommendation (#1684) --- document/core/text/lexical.rst | 10 ++++++---- document/core/util/macros.def | 1 + interpreter/Makefile | 2 +- interpreter/text/lexer.mll | 24 +++++++++++++----------- test/core/comments.wast | Bin 772 -> 1316 bytes 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/document/core/text/lexical.rst b/document/core/text/lexical.rst index 1dd34c863..4584b0c42 100644 --- a/document/core/text/lexical.rst +++ b/document/core/text/lexical.rst @@ -85,7 +85,9 @@ The allowed formatting characters correspond to a subset of the |ASCII|_ *format \production{white space} & \Tspace &::=& (\text{~~} ~|~ \Tformat ~|~ \Tcomment)^\ast \\ \production{format} & \Tformat &::=& - \unicode{09} ~|~ \unicode{0A} ~|~ \unicode{0D} \\ + \Tnewline ~|~ \unicode{09} \\ + \production{newline} & \Tnewline &::=& + \unicode{0A} ~|~ \unicode{0D} ~|~ \unicode{0D}~\unicode{0A} \\ \end{array} The only relevance of white space is to separate :ref:`tokens `. It is otherwise ignored. @@ -107,13 +109,13 @@ Block comments can be nested. \production{comment} & \Tcomment &::=& \Tlinecomment ~|~ \Tblockcomment \\ \production{line comment} & \Tlinecomment &::=& - \Tcommentd~~\Tlinechar^\ast~~(\unicode{0A} ~|~ \T{eof}) \\ + \Tcommentd~~\Tlinechar^\ast~~(\Tnewline ~|~ \T{eof}) \\ \production{line character} & \Tlinechar &::=& - c{:}\Tchar & (\iff c \neq \unicode{0A}) \\ + c{:}\Tchar & (\iff c \neq \unicode{0A} \land c \neq \unicode{0D}) \\ \production{block comment} & \Tblockcomment &::=& \Tcommentl~~\Tblockchar^\ast~~\Tcommentr \\ \production{block character} & \Tblockchar &::=& - c{:}\Tchar & (\iff c \neq \text{;} \wedge c \neq \text{(}) \\ &&|& + c{:}\Tchar & (\iff c \neq \text{;} \land c \neq \text{(}) \\ &&|& \text{;} & (\iff~\mbox{the next character is not}~\text{)}) \\ &&|& \text{(} & (\iff~\mbox{the next character is not}~\text{;}) \\ &&|& \Tblockcomment \\ diff --git a/document/core/util/macros.def b/document/core/util/macros.def index df4af62f8..5e7a4889b 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -700,6 +700,7 @@ .. |Tchar| mathdef:: \xref{text/lexical}{text-char}{\T{char}} .. |Tspace| mathdef:: \xref{text/lexical}{text-space}{\T{space}} .. |Tformat| mathdef:: \xref{text/lexical}{text-format}{\T{format}} +.. |Tnewline| mathdef:: \xref{text/lexical}{text-newline}{\T{newline}} .. |Ttoken| mathdef:: \xref{text/lexical}{text-token}{\T{token}} .. |Tkeyword| mathdef:: \xref{text/lexical}{text-keyword}{\T{keyword}} diff --git a/interpreter/Makefile b/interpreter/Makefile index 5939f838e..dfd9064bb 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -33,7 +33,7 @@ zip: $(ZIP) # Building -.PHONY: $(NAME) $(JSLIB) +.PHONY: $(NAME) $(JSLIB) $(NAME): rm -f $@ diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index d9a12b5d2..34099e849 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -27,9 +27,9 @@ let string s = while !i < String.length s - 1 do let c = if s.[!i] <> '\\' then s.[!i] else match (incr i; s.[!i]) with - | 'n' -> '\n' - | 'r' -> '\r' - | 't' -> '\t' + | 'n' -> '\x0a' + | 'r' -> '\x0d' + | 't' -> '\x09' | '\\' -> '\\' | '\'' -> '\'' | '\"' -> '\"' @@ -61,10 +61,12 @@ let letter = ['a'-'z''A'-'Z'] let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] -let space = [' ''\t''\n''\r'] +let ascii_newline = ['\x0a''\x0d'] +let newline = ascii_newline | "\x0a\x0d" +let space = [' ''\x09''\x0a''\x0d'] let control = ['\x00'-'\x1f'] # space let ascii = ['\x00'-'\x7f'] -let ascii_no_nl = ascii # '\x0a' +let ascii_no_nl = ascii # ascii_newline let utf8cont = ['\x80'-'\xbf'] let utf8enc = ['\xc2'-'\xdf'] utf8cont @@ -127,8 +129,8 @@ rule token = parse | float as s { FLOAT s } | string as s { STRING (string s) } - | '"'character*('\n'|eof) { error lexbuf "unclosed string literal" } - | '"'character*['\x00'-'\x09''\x0b'-'\x1f''\x7f'] + | '"'character*(newline|eof) { error lexbuf "unclosed string literal" } + | '"'character*(control#ascii_newline) { error lexbuf "illegal control character in string literal" } | '"'character*'\\'_ { error_nest (Lexing.lexeme_end_p lexbuf) lexbuf "illegal escape" } @@ -698,11 +700,11 @@ rule token = parse | id as s { VAR s } | ";;"utf8_no_nl*eof { EOF } - | ";;"utf8_no_nl*'\n' { Lexing.new_line lexbuf; token lexbuf } + | ";;"utf8_no_nl*newline { Lexing.new_line lexbuf; token lexbuf } | ";;"utf8_no_nl* { token lexbuf (* causes error on following position *) } | "(;" { comment (Lexing.lexeme_start_p lexbuf) lexbuf; token lexbuf } - | space#'\n' { token lexbuf } - | '\n' { Lexing.new_line lexbuf; token lexbuf } + | space#ascii_newline { token lexbuf } + | newline { Lexing.new_line lexbuf; token lexbuf } | eof { EOF } | reserved { unknown lexbuf } @@ -713,7 +715,7 @@ rule token = parse and comment start = parse | ";)" { () } | "(;" { comment (Lexing.lexeme_start_p lexbuf) lexbuf; comment start lexbuf } - | '\n' { Lexing.new_line lexbuf; comment start lexbuf } + | newline { Lexing.new_line lexbuf; comment start lexbuf } | utf8_no_nl { comment start lexbuf } | eof { error_nest start lexbuf "unclosed comment" } | _ { error lexbuf "malformed UTF-8 encoding" } diff --git a/test/core/comments.wast b/test/core/comments.wast index c291370fa72141c02e627c6edf0442bd409129cf..5ef64a6c1e60e898c86f51a53dcb11201e5025f8 100644 GIT binary patch literal 1316 zcmbtTJ8u**5au0X5D?yPMqAkuhwf2OxI#z~X=p&AISE~MXNiT+2CtXoD*gi%qM_zL z(B%i^FEGBn_4@7<34#mnjOUy08_#&9gtu6E$nA8B#zQqTesaK=l#7#K#>E)WN@6^5 zrnaaxc0tjZ#32Gt*r3_DWQ>Os+80udv*N9~v6e+Hk1G%pndsIMd$#PYx^thZd-3Mw z&JOhZy}|ZVc)m@9r%sb0%wH*Vg#edq4I`wt#Idi>;TAf`-H zYu($Od4$qxZTGPNMNKW##G{_U?hMcrJzMtLUKgmS{|AyLWbsP6V`qu`)^seW&TY#(k{}g2UW? zFv=@yV$JZmwjQbSjF+{^f#bm^>pYCJaxl&WaEDc`J*d%8WC2EZB>P!z4gFe!_KZ{( z_ZaslEzY5@ok{US(Im8>##>V!o=~~?Z{^WRmD?Lpd;aR$Vf2%#Lg(K{y!m23B2eQ) S-@7JL(~idu{{cH%$NmAx5ppO1 delta 14 VcmZ3&)xx&HfRT}RvmxVUMgShv1K|Jw From 92fbea708bf0bbaae1106cc111004843cd20c418 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 1 Nov 2023 06:54:47 +0100 Subject: [PATCH 32/33] [spec] Cleaner definition of frames (#1697) --- document/core/exec/runtime.rst | 11 +++++++---- document/core/util/macros.def | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/document/core/exec/runtime.rst b/document/core/exec/runtime.rst index 6c53a4e96..c7a6b9819 100644 --- a/document/core/exec/runtime.rst +++ b/document/core/exec/runtime.rst @@ -419,6 +419,7 @@ It filters out entries of a specific kind in an order-preserving fashion: pair: abstract syntax; frame pair: abstract syntax; label .. _syntax-frame: +.. _syntax-framestate: .. _syntax-label: .. _frame: .. _label: @@ -486,6 +487,8 @@ and a reference to the function's own :ref:`module instance ` .. math:: \begin{array}{llll} \production{frame} & \frame &::=& + \FRAME_n\{ \framestate \} \\ + \production{frame state} & \framestate &::=& \{ \ALOCALS~\val^\ast, \AMODULE~\moduleinst \} \\ \end{array} @@ -499,7 +502,7 @@ Conventions * The meta variable :math:`L` ranges over labels where clear from context. -* The meta variable :math:`F` ranges over frames where clear from context. +* The meta variable :math:`F` ranges over frame states where clear from context. * The following auxiliary definition takes a :ref:`block type ` and looks up the :ref:`function type ` that it denotes in the current frame: @@ -534,7 +537,7 @@ In order to express the reduction of :ref:`traps `, :ref:`calls ` and an executing *thread*. A thread is a computation over :ref:`instructions ` -that operates relative to a current :ref:`frame ` referring to the :ref:`module instance ` in which the computation runs, i.e., where the current function originates from. +that operates relative to the state of a current :ref:`frame ` referring to the :ref:`module instance ` in which the computation runs, i.e., where the current function originates from. .. math:: \begin{array}{llcl} \production{configuration} & \config &::=& \store; \thread \\ \production{thread} & \thread &::=& - \frame; \instr^\ast \\ + \framestate; \instr^\ast \\ \end{array} .. note:: diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 5e7a4889b..2ae99bdee 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -1056,6 +1056,7 @@ .. |label| mathdef:: \xref{exec/runtime}{syntax-label}{\X{label}} .. |frame| mathdef:: \xref{exec/runtime}{syntax-frame}{\X{frame}} +.. |framestate| mathdef:: \xref{exec/runtime}{syntax-framestate}{\X{framestate}} .. Stack, meta functions From 3be4c2fb1b44f5b48ccb43af1f314dc3dc8ca6ec Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 7 Nov 2023 07:20:40 +0100 Subject: [PATCH 33/33] [spec] Fix definition of lane ops + better xrefs (#1700) --- document/core/appendix/index-instructions.py | 3 +- document/core/exec/instructions.rst | 52 +++++++++++--------- document/core/exec/numerics.rst | 17 ++++--- document/core/util/macros.def | 6 +++ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/document/core/appendix/index-instructions.py b/document/core/appendix/index-instructions.py index c3ffc2a32..8ffedcca3 100755 --- a/document/core/appendix/index-instructions.py +++ b/document/core/appendix/index-instructions.py @@ -54,8 +54,7 @@ def RefWrap(s, kind): def Instruction(name, opcode, type=None, validation=None, execution=None, operator=None): if operator: - execution_str = ', '.join([RefWrap(execution, 'execution'), - RefWrap(operator, 'operator')]) + execution_str = RefWrap(execution, 'execution') + ' (' + RefWrap(operator, 'operator') + ')' else: execution_str = RefWrap(execution, 'execution') diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index ccb27bfd3..74802d6de 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -20,16 +20,15 @@ The mapping of numeric instructions to their underlying operators is expressed b .. math:: \begin{array}{lll@{\qquad}l} - \X{op}_{\IN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\ - \X{op}_{\FN}(z_1,\dots,z_k) &=& \F{f}\X{op}_N(z_1,\dots,z_k) \\ - \X{op}_{\VN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\ + \X{op}_{\IN}(i_1,\dots,i_k) &=& \xref{exec/numerics}{int-ops}{\F{i}\X{op}}_N(i_1,\dots,i_k) \\ + \X{op}_{\FN}(z_1,\dots,z_k) &=& \xref{exec/numerics}{float-ops}{\F{f}\X{op}}_N(z_1,\dots,z_k) \\ \end{array} And for :ref:`conversion operators `: .. math:: \begin{array}{lll@{\qquad}l} - \X{cvtop}^{\sx^?}_{t_1,t_2}(c) &=& \X{cvtop}^{\sx^?}_{|t_1|,|t_2|}(c) \\ + \cvtop^{\sx^?}_{t_1,t_2}(c) &=& \xref{exec/numerics}{convert-ops}{\X{cvtop}}^{\sx^?}_{|t_1|,|t_2|}(c) \\ \end{array} Where the underlying operators are partial, the corresponding instruction will :ref:`trap ` when the result is not defined. @@ -64,9 +63,9 @@ Where the underlying operators are non-deterministic, because they may return on 2. Pop the value :math:`t.\CONST~c_1` from the stack. -3. If :math:`\unop_t(c_1)` is defined, then: +3. If :math:`\unopF_t(c_1)` is defined, then: - a. Let :math:`c` be a possible result of computing :math:`\unop_t(c_1)`. + a. Let :math:`c` be a possible result of computing :math:`\unopF_t(c_1)`. b. Push the value :math:`t.\CONST~c` to the stack. @@ -77,9 +76,9 @@ Where the underlying operators are non-deterministic, because they may return on .. math:: \begin{array}{lcl@{\qquad}l} (t\K{.}\CONST~c_1)~t\K{.}\unop &\stepto& (t\K{.}\CONST~c) - & (\iff c \in \unop_t(c_1)) \\ + & (\iff c \in \unopF_t(c_1)) \\ (t\K{.}\CONST~c_1)~t\K{.}\unop &\stepto& \TRAP - & (\iff \unop_{t}(c_1) = \{\}) + & (\iff \unopF_{t}(c_1) = \{\}) \end{array} @@ -94,9 +93,9 @@ Where the underlying operators are non-deterministic, because they may return on 3. Pop the value :math:`t.\CONST~c_1` from the stack. -4. If :math:`\binop_t(c_1, c_2)` is defined, then: +4. If :math:`\binopF_t(c_1, c_2)` is defined, then: - a. Let :math:`c` be a possible result of computing :math:`\binop_t(c_1, c_2)`. + a. Let :math:`c` be a possible result of computing :math:`\binopF_t(c_1, c_2)`. b. Push the value :math:`t.\CONST~c` to the stack. @@ -107,9 +106,9 @@ Where the underlying operators are non-deterministic, because they may return on .. math:: \begin{array}{lcl@{\qquad}l} (t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\binop &\stepto& (t\K{.}\CONST~c) - & (\iff c \in \binop_t(c_1,c_2)) \\ + & (\iff c \in \binopF_t(c_1,c_2)) \\ (t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\binop &\stepto& \TRAP - & (\iff \binop_{t}(c_1,c_2) = \{\}) + & (\iff \binopF_{t}(c_1,c_2) = \{\}) \end{array} @@ -122,14 +121,14 @@ Where the underlying operators are non-deterministic, because they may return on 2. Pop the value :math:`t.\CONST~c_1` from the stack. -3. Let :math:`c` be the result of computing :math:`\testop_t(c_1)`. +3. Let :math:`c` be the result of computing :math:`\testopF_t(c_1)`. 4. Push the value :math:`\I32.\CONST~c` to the stack. .. math:: \begin{array}{lcl@{\qquad}l} (t\K{.}\CONST~c_1)~t\K{.}\testop &\stepto& (\I32\K{.}\CONST~c) - & (\iff c = \testop_t(c_1)) \\ + & (\iff c = \testopF_t(c_1)) \\ \end{array} @@ -144,14 +143,14 @@ Where the underlying operators are non-deterministic, because they may return on 3. Pop the value :math:`t.\CONST~c_1` from the stack. -4. Let :math:`c` be the result of computing :math:`\relop_t(c_1, c_2)`. +4. Let :math:`c` be the result of computing :math:`\relopF_t(c_1, c_2)`. 5. Push the value :math:`\I32.\CONST~c` to the stack. .. math:: \begin{array}{lcl@{\qquad}l} (t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\relop &\stepto& (\I32\K{.}\CONST~c) - & (\iff c = \relop_t(c_1,c_2)) \\ + & (\iff c = \relopF_t(c_1,c_2)) \\ \end{array} @@ -256,20 +255,27 @@ Reference Instructions Vector Instructions ~~~~~~~~~~~~~~~~~~~ -Most vector instructions are defined in terms of generic numeric operators applied lane-wise based on the :ref:`shape `. +Vector instructions that operate bitwise are handled as integer operations of respective width. .. math:: \begin{array}{lll@{\qquad}l} + \X{op}_{\VN}(i_1,\dots,i_k) &=& \xref{exec/numerics}{int-ops}{\F{i}\X{op}}_N(i_1,\dots,i_k) \\ + \end{array} + +Most other vector instructions are defined in terms of numeric operators that are applied lane-wise according to the given :ref:`shape `. + +.. math:: + \begin{array}{llll} \X{op}_{t\K{x}N}(n_1,\dots,n_k) &=& - \lanes^{-1}_{t\K{x}N}(op_t(\lanes_{t\K{x}N}(n_1) ~\dots~ \lanes_{t\K{x}N}(n_k)) + \lanes^{-1}_{t\K{x}N}(\xref{exec/instructions}{exec-instr-numeric}{\X{op}}_t(i_1,\dots,i_k)^\ast) & \qquad(\iff i_1^\ast = \lanes_{t\K{x}N}(n_1) \land \dots \land i_k^\ast = \lanes_{t\K{x}N}(n_k) \\ \end{array} .. note:: - For example, the result of instruction :math:`\K{i32x4}.\ADD` applied to operands :math:`i_1, i_2` - invokes :math:`\ADD_{\K{i32x4}}(i_1, i_2)`, which maps to - :math:`\lanes^{-1}_{\K{i32x4}}(\ADD_{\I32}(i_1^+, i_2^+))`, - where :math:`i_1^+` and :math:`i_2^+` are sequences resulting from invoking - :math:`\lanes_{\K{i32x4}}(i_1)` and :math:`\lanes_{\K{i32x4}}(i_2)` + For example, the result of instruction :math:`\K{i32x4}.\ADD` applied to operands :math:`v_1, v_2` + invokes :math:`\ADD_{\K{i32x4}}(v_1, v_2)`, which maps to + :math:`\lanes^{-1}_{\K{i32x4}}(\ADD_{\I32}(i_1, i_2)^\ast)`, + where :math:`i_1^\ast` and :math:`i_2^\ast` are sequences resulting from invoking + :math:`\lanes_{\K{i32x4}}(v_1)` and :math:`\lanes_{\K{i32x4}}(v_2)` respectively. diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index 85d3dbd00..b76190f6f 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -169,24 +169,25 @@ where :math:`M = \significand(N)` and :math:`E = \exponent(N)`. Vectors ....... -Numeric vectors have the same underlying representation as an |i128|. -They can also be interpreted as a sequence of numeric values packed into a |V128| with a particular |shape|. +Numeric vectors of type |VN| have the same underlying representation as an |IN|. +They can also be interpreted as a sequence of numeric values packed into a |VN| with a particular |shape| :math:`t\K{x}M`, +provided that :math:`N = |t|\cdot M`. .. math:: \begin{array}{l} \begin{array}{lll@{\qquad}l} - \lanes_{t\K{x}N}(c) &=& - c_0~\dots~c_{N-1} \\ + \lanes_{t\K{x}M}(c) &=& + c_0~\dots~c_{M-1} \\ \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}l@{~}l@{~}l} - (\where & B &=& |t| / 8 \\ - \wedge & b^{16} &=& \bytes_{\i128}(c) \\ - \wedge & c_i &=& \bytes_{t}^{-1}(b^{16}[i \cdot B \slice B])) + (\where & w &=& |t| / 8 \\ + \wedge & b^\ast &=& \bytes_{\IN}(c) \\ + \wedge & c_i &=& \bytes_{t}^{-1}(b^\ast[i \cdot w \slice w])) \end{array} \end{array} -These functions are bijections, so they are invertible. +This function is a bijection on |IN|, hence it is invertible. .. index:: byte, little endian, memory diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 2ae99bdee..1dcec42d2 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -500,6 +500,12 @@ .. |relop| mathdef:: \xref{syntax/instructions}{syntax-relop}{\X{relop}} .. |cvtop| mathdef:: \xref{syntax/instructions}{syntax-cvtop}{\X{cvtop}} +.. |unopF| mathdef:: \xref{exec/instructions}{exec-instr-numeric}{\X{unop}} +.. |binopF| mathdef:: \xref{exec/instructions}{exec-instr-numeric}{\X{binop}} +.. |testopF| mathdef:: \xref{exec/instructions}{exec-instr-numeric}{\X{testop}} +.. |relopF| mathdef:: \xref{exec/instructions}{exec-instr-numeric}{\X{relop}} +.. |cvtopF| mathdef:: \xref{exec/instructions}{exec-instr-numeric}{\X{cvtop}} + .. |iunop| mathdef:: \xref{syntax/instructions}{syntax-iunop}{\X{iunop}} .. |ibinop| mathdef:: \xref{syntax/instructions}{syntax-ibinop}{\X{ibinop}} .. |itestop| mathdef:: \xref{syntax/instructions}{syntax-itestop}{\X{itestop}}