diff --git a/.github/workflows/ci-interpreter.yml b/.github/workflows/ci-interpreter.yml index 7ac7513dd0..ed69768ebb 100644 --- a/.github/workflows/ci-interpreter.yml +++ b/.github/workflows/ci-interpreter.yml @@ -17,15 +17,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup OCaml - uses: ocaml/setup-ocaml@v2 + uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.14.x - name: Setup OCaml tools 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 + uses: actions/setup-node@v4 with: node-version: 20.x - name: Build interpreter diff --git a/.github/workflows/ci-spec.yml b/.github/workflows/ci-spec.yml index f5918416cf..82447e640f 100644 --- a/.github/workflows/ci-spec.yml +++ b/.github/workflows/ci-spec.yml @@ -17,11 +17,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: "recursive" - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 16 - name: Setup Bikeshed @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Bikeshed run: pip install bikeshed && bikeshed update - name: Run Bikeshed @@ -59,7 +59,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Bikeshed run: pip install bikeshed && bikeshed update - name: Run Bikeshed @@ -128,7 +128,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Upload artifacts uses: actions/upload-artifact@v4 with: @@ -147,7 +147,7 @@ jobs: - build-spec-versions steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Create output directory run: mkdir _output && cp document/index.html _output/index.html - name: Download core spec artifact @@ -187,7 +187,7 @@ jobs: path: _output/versions - name: Publish to GitHub Pages if: github.ref == 'refs/heads/main' - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: publish_dir: ./_output github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/w3c-publish.yml b/.github/workflows/w3c-publish.yml index cd43f17a33..bcb26699dd 100644 --- a/.github/workflows/w3c-publish.yml +++ b/.github/workflows/w3c-publish.yml @@ -1,9 +1,11 @@ -name: Publish to W3C TR space +name: Validate/Publish to W3C TR space on: push: branches: [ main ] paths: [ .github/**, document/** ] + pull_request: + paths: [ .github/**, document/** ] # Allows you to run this workflow manually from the Actions tab, gh CLI tool, # or REST API. THe w3c-status options correspond to the valid options for @@ -23,30 +25,45 @@ on: - CRD - CR +env: + YARN_ENABLE_IMMUTABLE_INSTALLS: false + W3C_STATUS: ${{ github.event_name == 'workflow_dispatch' && inputs.w3c-status || 'WD' }} + jobs: publish-to-w3c-TR: - if: github.repository == 'WebAssembly/spec' + strategy: + fail-fast: false + matrix: + spec: [core, js-api, web-api] runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: "recursive" - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 16 - name: Setup Bikeshed run: pip install bikeshed && bikeshed update - name: Setup TexLive + if: ${{ matrix.spec == 'core' }} run: sudo apt-get update -y && sudo apt-get install -y latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended - name: Setup Sphinx + if: ${{ matrix.spec == 'core' }} run: pip install six && pip install sphinx==5.1.0 - - name: Publish all specs to their https://www.w3.org/TR/ URLs - run: cd document && make -e WD-echidna-CI + - name: Publish ${{ matrix.spec }} spec to its https://www.w3.org/TR/ URL + if: env.W3C_ECHIDNA_TOKEN_CORE + run: cd document && make -e -C ${{ matrix.spec }} WD-echidna-CI env: - W3C_STATUS: ${{ github.event_name == 'push' && 'CRD' || inputs.w3c-status }} W3C_ECHIDNA_TOKEN_CORE: ${{ secrets.W3C_ECHIDNA_TOKEN_CORE }} W3C_ECHIDNA_TOKEN_JSAPI: ${{ secrets.W3C_ECHIDNA_TOKEN_JSAPI }} W3C_ECHIDNA_TOKEN_WEBAPI: ${{ secrets.W3C_ECHIDNA_TOKEN_WEBAPI }} - YARN_ENABLE_IMMUTABLE_INSTALLS: false + ECHIDNA_DRYRUN: ${{ !(github.event_name == 'push' && github.repository == 'WebAssembly/spec' && github.ref == 'refs/heads/main') }} + - name: Validate ${{ matrix.spec }} spec with Echidna + if: env.W3C_USERNAME + run: cd document && make -e -C ${{ matrix.spec }} WD-echidna + env: + W3C_USERNAME: ${{ secrets.W3C_USERNAME }} + W3C_PASSWORD: ${{ secrets.W3C_PASSWORD }} diff --git a/document/core/Makefile b/document/core/Makefile index df245c881c..f0016afd8f 100644 --- a/document/core/Makefile +++ b/document/core/Makefile @@ -13,6 +13,7 @@ NAME = WebAssembly DECISION_URL = https://github.com/WebAssembly/meetings/blob/main/main/2024/WG-06-12.md TAR = tar DEADLINE = $(shell date -d "+30 days" +%Y-%m-%d 2>/dev/null || date -v +30d +%Y-%m-%d) +ECHIDNA_DRYRUN = true # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 @@ -196,9 +197,11 @@ WD-echidna: WD-tar 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 + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) @echo - @echo "Published $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" .PHONY: WD-echidna-CI WD-echidna-CI: WD-tar @@ -210,9 +213,11 @@ WD-echidna-CI: WD-tar curl 'https://labs.w3.org/echidna/api/request' \ -F "tar=@$(BUILDDIR)/WD.tar" \ -F "token=$(W3C_ECHIDNA_TOKEN_CORE)" \ - -F "decision=$(DECISION_URL)" | tee $(BUILDDIR)/WD-echidna-id.txt + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) @echo - @echo "Published $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" .PHONY: diff diff: bikeshed diff --git a/document/core/exec/modules.rst b/document/core/exec/modules.rst index d40a22cfac..c9618231e6 100644 --- a/document/core/exec/modules.rst +++ b/document/core/exec/modules.rst @@ -441,7 +441,7 @@ and list of :ref:`reference ` vectors for the module's :ref:`element 24. Let :math:`\exportinst^\ast` be the concatenation of the :ref:`export instances ` :math:`\exportinst_i` in index order. -25. Let :math:`\moduleinst` be the :ref:`module instance ` :math:`\{\MITYPES~\deftype^\ast,` :math:`\MIFUNCS~\funcaddr_{\F{mod}}^\ast,` :math:`\MITABLES~\tableaddr_{\F{mod}}^\ast,` :math:`\MIMEMS~\memaddr_{\F{mod}}^\ast,` :math:`\MIGLOBALS~\globaladdr_{\F{mod}}^\ast,` :math:`\MITAGS~\tagaddr_{\F{mod}}^\ast`, :math:`\MIEXPORTS~\exportinst^\ast\}`. +25. Let :math:`\moduleinst` be the :ref:`module instance ` :math:`\{\MITYPES~\deftype^\ast,` :math:`\MIFUNCS~\funcaddr_{\F{mod}}^\ast,` :math:`\MITABLES~\tableaddr_{\F{mod}}^\ast,` :math:`\MIMEMS~\memaddr_{\F{mod}}^\ast,` :math:`\MIGLOBALS~\globaladdr_{\F{mod}}^\ast,` :math:`\MITAGS~\tagaddr_{\F{mod}}^\ast`, :math:`\MIELEMS~\elemaddr^\ast,` :math:`\MIDATAS~\dataaddr^\ast,` :math:`\MIEXPORTS~\exportinst^\ast\}`. 26. Return :math:`\moduleinst`. diff --git a/document/core/util/bikeshed_fixup.py b/document/core/util/bikeshed_fixup.py index bcef6c1af1..af9a029d42 100755 --- a/document/core/util/bikeshed_fixup.py +++ b/document/core/util/bikeshed_fixup.py @@ -12,11 +12,7 @@ def Main(): data = open(sys.argv[1]).read() - # Make bikeshed happy - # Apparently it can't handle empty line before DOCTYPE comment - data = data.replace('\n - data = data.replace('
', '\n
')
+  # Clean up the input for Bikeshed
 
   # Don't add more than 3 levels to TOC.
   data = data.replace('
', '
') @@ -34,7 +30,8 @@ def Main(): 'Validation Algorithm', 'Custom Sections', 'Soundness', - 'Changes', + 'Type System Properties', + 'Change History', 'Index of Types', 'Index of Instructions', 'Index of Semantic Rules']: @@ -43,18 +40,6 @@ def Main(): '

A.' + str(number) + ' ' + section + '

') number += 1 - - # Drop spurious navigation. - data = data.replace( -""" - """, '') - # Use bikeshed biblio references for unicode and IEEE754 data = data.replace( """Unicode""", @@ -88,6 +73,9 @@ def Main(): r'\1', data, flags=re.DOTALL) + # Escape some latex sequences that Bikeshed interprets as macros + data = data.replace(r' \\[1ex]', r' \\\[1ex]') + sys.stdout.write(data) Main() diff --git a/document/js-api/Makefile b/document/js-api/Makefile index 7893918d46..acd14cf25d 100644 --- a/document/js-api/Makefile +++ b/document/js-api/Makefile @@ -6,6 +6,7 @@ NAME = WebAssembly DECISION_URL = https://github.com/WebAssembly/meetings/blob/main/main/2024/WG-06-12.md TAR = tar DEADLINE = $(shell date -d "+30 days" +%Y-%m-%d 2>/dev/null || date -v +30d +%Y-%m-%d) +ECHIDNA_DRYRUN = true .PHONY: all all: @@ -35,7 +36,6 @@ diff: all # macOS tar has no “--transform” option (only GNU tar does), so on macOS, # do “brew install tar” & run “make” like this: “TAR=gtar make -e WD-tar” WD-tar: all - bikeshed spec --md-status=$(W3C_STATUS) --md-deadline=$(DEADLINE) index.bs $(BUILDDIR)/html/index.html $(TAR) -C $(BUILDDIR)/html --transform="s/index.html/Overview.html/" -cf $(BUILDDIR)/WD.tar index.html @echo "Built $(BUILDDIR)/WD.tar." @@ -50,7 +50,11 @@ WD-echidna: WD-tar 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 + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) + @echo + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" .PHONY: WD-echidna-CI WD-echidna-CI: WD-tar @@ -62,6 +66,8 @@ WD-echidna-CI: WD-tar curl 'https://labs.w3.org/echidna/api/request' \ -F "tar=@$(BUILDDIR)/WD.tar" \ -F "token=$(W3C_ECHIDNA_TOKEN_JSAPI)" \ - -F "decision=$(DECISION_URL)" | tee $(BUILDDIR)/WD-echidna-id.txt + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) @echo - @echo "Published $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" diff --git a/document/js-api/index.bs b/document/js-api/index.bs index dc8f557edc..6295ec1465 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -23,6 +23,12 @@ Date: now "title": "WebAssembly Core Specification", "publisher": "W3C WebAssembly Community Group", "status": "Draft" + }, + "WASMWEB": { + "href": "https://webassembly.github.io/spec/js-api/", + "title": "WebAssembly Web API Specification", + "publisher": "W3C WebAssembly Community Group", + "status": "Draft" } }
@@ -65,10 +71,17 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT text: ℤ; url: #ℤ text: mathematical value; url: #mathematical-value text: SameValue; url: sec-samevalue + text: Array; url: sec-array-exotic-objects + text: BigInt; url: sec-ecmascript-language-types-bigint-type urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: dfn + text: embedding interface; url: appending/embedding.html + text: scope; url: intro/introduction.html#scope url: valid/modules.html#valid-module text: valid text: WebAssembly module validation + text: valid limits; url: valid/types.html#valid-limits + text: valid memtype; url: valid/types.html#valid-memtype + text: valid tabletype; url: valid/types.html#valid-tabletype text: module grammar; url: binary/modules.html#binary-module text: custom section; url: binary/modules.html#custom-section text: customsec; url: binary/modules.html#binary-customsec @@ -125,9 +138,11 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df text: error; url: appendix/embedding.html#embed-error text: store; url: exec/runtime.html#syntax-store text: address type; url: syntax/types.html#syntax-addrtype + text: limits; url: syntax/types.html#syntax-limits text: table type; url: syntax/types.html#syntax-tabletype text: table address; url: exec/runtime.html#syntax-tableaddr text: function address; url: exec/runtime.html#syntax-funcaddr + text: memory type; url: syntax/types.html#syntax-memtype text: memory address; url: exec/runtime.html#syntax-memaddr text: global address; url: exec/runtime.html#syntax-globaladdr text: tag address; url: exec/runtime.html#syntax-tagaddr @@ -235,7 +250,14 @@ emu-const { } -This API provides a way to access WebAssembly [[WEBASSEMBLY]] through a bridge to explicitly construct modules from JavaScript [[ECMASCRIPT]]. +

Introduction

+ +By design, the [=scope=] of the WebAssembly core specification [[WEBASSEMBLY]] does not include a description of how WebAssembly programs interact with their surrounding execution environment. +Instead it defines an abstract [=embedding interface=] between WebAssembly and its environment, (called the *embedder*). +It is only through this interface that an embedder interacts with the semantics of WebAssembly, and the embedder implements the connection between its host environment and the embedding API. +This document describes the embedding of WebAssembly into JavaScript [[ECMASCRIPT]] environments, including how WebAssembly modules can be constructed and instantiated, how imported and exported functions are called, how data is exchanged, and how errors are handled. +When the JavaScript environment is itself embedded in a Web browser, the Web API spec [[WASMWEB]] describes additional behavior relevant to the Web environment. +

Sample API Usage

@@ -751,8 +773,8 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32". 1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|). 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty. - 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. - 1. Let |memtype| be |addrtype| { **min** |initial|, **max** |maximum| }. + 1. Let |memtype| be [=memory type=] |addrtype| { **min** |initial|, **max** |maximum| }. + 1. If |memtype| is not [=valid memtype|valid=], throw a {{RangeError}} exception. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let (|store|, |memaddr|) be [=mem_alloc=](|store|, |memtype|). If allocation fails, throw a {{RangeError}} exception. 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. @@ -918,15 +940,15 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address 1. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32". 1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|). 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty. - 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. + 1. Let |type| be the [=table type=] |addrtype| { [=limits|min=] |initial|, [=limits|max=] |maximum| } |elementType|. + 1. If |type| is not [=valid tabletype|valid=], throw a {{RangeError}} exception. 1. If |value| is missing, 1. Let |ref| be [=DefaultValue=](|elementtype|). 1. Assert: |ref| is not [=error=]. 1. Otherwise, - 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementtype|). - 1. Let |type| be the [=table type=] (|addrtype|, { **min** |initial|, **max** |maximum| }, |elementtype|). + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). + 1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). If allocation fails, throw a {{RangeError}} exception. 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. [=initialize a table object|Initialize=] **this** from |tableaddr|. @@ -1789,3 +1811,29 @@ In practice, an implementation may run out of resources for valid modules below

This section is non-normative.

This document defines a host environment for WebAssembly. It enables a WebAssembly instance to [=import=] JavaScript objects and functions from an [=read the imports|import object=], but otherwise provides no access to the embedding environment. Thus a WebAssembly instance is bound to the same constraints as JavaScript. + +

Change History

+ +

This section is non-normative.

+ +

Since the original release 1.0 of the WebAssembly specification, a number of proposals for extensions have been integrated. +The following sections provide an overview of what has changed.

+ +

Release 2.0

+ +

Multiple Values

+Multiple values can be returned to and from JavaScript functions as an [=Array=] object. + +

BigInt Integration

+WebAssembly [=i64=] values can be passed to and from JavaScript (via imported or exported globals, table get or set operations, function return values or arguments) as [=BigInt=] objects. + +

Reference Types

+JavaScript values can be passed to and from WebAssembly (via imported or exported globals, table set or get operations, and function arguments or return values) as [=externref=] values. + +

Multiple Tables

+Multiple tables can be exported and imported to and from JavaScript. + +

Release 3.0

+ +

Multiple Memories

+Multiple memories can be exported and imported to and from JavaScript. diff --git a/document/util/check-echidna-status.py b/document/util/check-echidna-status.py new file mode 100755 index 0000000000..9bc3f6026c --- /dev/null +++ b/document/util/check-echidna-status.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +from datetime import datetime, timedelta +import json +import os +import requests +import sys +import time + +ECHIDNA_ID_FILE = 'WD-echidna-id.txt' +ECHIDNA_STATUS_URL = 'http://labs.w3.org/echidna/api/status?id=' + + +def get_echidna_id(directory): + id_file = os.path.join(directory, ECHIDNA_ID_FILE) + file_time = os.path.getmtime(id_file) + if datetime.fromtimestamp(file_time) < datetime.now() - timedelta(hours=1): + print(f'Warning: Echidna ID is not recent: timestamp is {file_time}') + with open(id_file, 'r') as f: + return f.read().strip() + + +def get_current_response(echidna_id): + url = ECHIDNA_STATUS_URL + echidna_id + print(f'Fetching {url}') + response = requests.get(url, allow_redirects=True) + if response.status_code != 200: + print(f'Got status code {response.status_code}, text:') + print(response.text) + raise Exception('Failed to fetch echidna result') + + return response.json() + + +def get_echidna_result(echidna_id): + response = get_current_response(echidna_id) + while response['results']['status'] == 'started': + time.sleep(5) + print('Echidna run in progress, retrying...') + response = get_current_response(echidna_id) + + result = response['results']['status'] + print(f'Echidna issue {echidna_id} is {result}.') + print(json.dumps(response, indent=2)) + return result == 'success' + + +def main(argv): + directory = os.getcwd() if len(argv) < 2 else argv[1] + echidna_id = get_echidna_id(directory) + print(f'Got echidna id {echidna_id}.') + time.sleep(5) + if not get_echidna_result(echidna_id): + sys.exit(1) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/document/web-api/Makefile b/document/web-api/Makefile index 2ea8f11ac5..0deb3d9d4d 100644 --- a/document/web-api/Makefile +++ b/document/web-api/Makefile @@ -6,6 +6,7 @@ NAME = WebAssembly DECISION_URL = https://github.com/WebAssembly/meetings/blob/main/main/2024/WG-06-12.md TAR = tar DEADLINE = $(shell date -d "+30 days" +%Y-%m-%d 2>/dev/null || date -v +30d +%Y-%m-%d) +ECHIDNA_DRYRUN = true .PHONY: all all: @@ -35,7 +36,6 @@ diff: all # macOS tar has no “--transform” option (only GNU tar does), so on macOS, # do “brew install tar” & run “make” like this: “TAR=gtar make -e WD-tar” WD-tar: all - bikeshed spec --md-status=$(W3C_STATUS) --md-deadline=$(DEADLINE) index.bs $(BUILDDIR)/html/index.html $(TAR) -C $(BUILDDIR)/html --transform="s/index.html/Overview.html/" -cf $(BUILDDIR)/WD.tar index.html @echo "Built $(BUILDDIR)/WD.tar." @@ -50,7 +50,11 @@ WD-echidna: WD-tar 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 + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) + @echo + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" .PHONY: WD-echidna-CI WD-echidna-CI: WD-tar @@ -62,6 +66,8 @@ WD-echidna-CI: WD-tar curl 'https://labs.w3.org/echidna/api/request' \ -F "tar=@$(BUILDDIR)/WD.tar" \ -F "token=$(W3C_ECHIDNA_TOKEN_WEBAPI)" \ - -F "decision=$(DECISION_URL)" | tee $(BUILDDIR)/WD-echidna-id.txt + -F "decision=$(DECISION_URL)" \ + -F "dry-run=$(ECHIDNA_DRYRUN)" | tee $(BUILDDIR)/WD-echidna-id.txt + python3 ../util/check-echidna-status.py $(BUILDDIR) @echo - @echo "Published $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" + @echo "Uploaded $(W3C_STATUS). Check its status at https://labs.w3.org/echidna/api/status?id=`cat $(BUILDDIR)/WD-echidna-id.txt`" diff --git a/document/web-api/index.bs b/document/web-api/index.bs index db58b4495b..a63ee60bbc 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -18,12 +18,6 @@ Date: now
 {
-  "ECMA-262": {
-    "href": "https://tc39.github.io/ecma262",
-    "title": "ECMAScript® Language Specification",
-    "publisher": "ECMA TC39",
-    "status": "Current Editor's Draft"
-  },
   "WEBASSEMBLY": {
     "href": "https://webassembly.github.io/spec/core/",
     "title": "WebAssembly Core Specification",
@@ -46,7 +40,7 @@ Date: now
 
-urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
+urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT
     type: exception; for: ECMAScript
         text: TypeError; url: sec-native-error-types-used-in-this-standard-typeerror
     type: interface
@@ -78,12 +72,16 @@ url:https://w3c.github.io/webappsec-secure-contexts/#environment-settings-object
 
+ +

Introduction

This document builds off of the WebAssembly specification [[WEBASSEMBLY]] and the WebAssembly JavaScript embedding [[WASMJS]]. +It describes the integration of WebAssembly into the broader Web platform, for example with +additional APIs that are implemented by Web user agents but are outside the scope of JavaScript [[ECMASCRIPT]] itself.

Streaming Module Compilation and Instantiation

@@ -242,8 +240,8 @@ JavaScript.

Media-type Registration

-This section will be submitted to the Internet Engineering Steering Group (IESG) for -review, approval, and registration with IANA. +The media type `application/wasm` has been registered with the IANA media type database [[IANA-MEDIA-TYPES]], +with the following registration template: application/wasm @@ -312,3 +310,27 @@ application/wasm
Author/Change Controller:
W3C
+ + +

Security and Privacy Considerations

+ +

This section is non-normative.

+WebAssembly provides no access to the surrounding environment other than via the JavaScript API described in the [[WASMJS|JS API]] specification. +Therefore, WebAssembly cannot collect or expose any information (personal, sensitive or otherwise) to Web sites or other parties beyond what can be collected, exposed or processed with JavaScript. +WebAssembly memory has the same lifetime as the objects in the surrounding JavaScript environment and is not persisted or serialized (other than by copying it out to JavaScript and using existing serialization APIs). +No access is provided to the underlying platform or hardware, or to other devices, or to the user agent’s native UI. + +WebAssembly is an additional program execution mechanism, and can be executed wherever JavaScript can be executed. +Therefore the threat model is essentially the same as for JavaScript code, and has similar considerations for delivery (e.g. WebAssembly code should be protected in transit from active and passive network attackers) +and policy (e.g. some loading mechanisms or execution are restricted via mechanisms such as the same-origin policy or Content Security Policy). + +

Change History

+ +

This section is non-normative.

+ +

Since the original release 1.0 of the WebAssembly specification, a number of proposals for extensions have been integrated. +The following sections provide an overview of what has changed.

+ +

Release 2.0

+

Media-type Registraton Completed

+The registration for the `application/wasm` media type has been successfully completed. diff --git a/test/build.py b/test/build.py index 69c1b19a26..94e7304dbf 100755 --- a/test/build.py +++ b/test/build.py @@ -13,6 +13,9 @@ WASM_EXEC = os.path.join(INTERPRETER_DIR, 'wasm') WAST_TESTS_DIR = os.path.join(SCRIPT_DIR, 'core') +WAST_TEST_SUBDIRS = [os.path.basename(d) for d in + filter(os.path.isdir, + glob.glob(os.path.join(WAST_TESTS_DIR, '*')))] HARNESS_DIR = os.path.join(SCRIPT_DIR, 'harness') HARNESS_FILES = ['testharness.js', 'testharnessreport.js', 'testharness.css'] @@ -67,13 +70,17 @@ def convert_wast_to_js(out_js_dir): inputs = [] - for wast_file in glob.glob(os.path.join(WAST_TESTS_DIR, '*.wast')): + for wast_file in glob.glob(os.path.join(WAST_TESTS_DIR, '**/*.wast'), + recursive = True): # Don't try to compile tests that are supposed to fail. if '.fail.' in wast_file: continue + js_subdir = os.path.basename(os.path.dirname(wast_file)) + if js_subdir == 'core': + js_subdir = '' js_filename = os.path.basename(wast_file) + '.js' - js_file = os.path.join(out_js_dir, js_filename) + js_file = os.path.join(out_js_dir, js_subdir, js_filename) inputs.append((wast_file, js_file)) pool = mp.Pool(processes=8) @@ -112,9 +119,9 @@ def build_js(out_js_dir): - - - + + +
""" @@ -137,6 +144,8 @@ def wrap_single_test(js_file): def build_html_js(out_dir): ensure_empty_dir(out_dir) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(out_dir, d)) copy_harness_files(out_dir, True) tests = convert_wast_to_js(out_dir) @@ -146,19 +155,25 @@ def build_html_js(out_dir): def build_html_from_js(tests, html_dir, use_sync): for js_file in tests: - js_filename = os.path.basename(js_file) - html_filename = js_filename + '.html' - html_file = os.path.join(html_dir, html_filename) + subdir = os.path.basename(os.path.dirname(js_file)) + js_prefix = '../js' + if subdir == 'js': + subdir = '' + js_prefix = './js' + js_filename = os.path.join(js_prefix, subdir, os.path.basename(js_file)) + html_filename = os.path.basename(js_file) + '.html' + html_file = os.path.join(html_dir, subdir, html_filename) js_harness = "sync_index.js" if use_sync else "async_index.js" + harness_dir = os.path.join(js_prefix, 'harness') with open(html_file, 'w+') as f: - content = HTML_HEADER.replace('{PREFIX}', './js/harness') \ - .replace('{WPT_PREFIX}', './js/harness') \ + content = HTML_HEADER.replace('{PREFIX}', harness_dir) \ + .replace('{WPT_PREFIX}', harness_dir) \ .replace('{JS_HARNESS}', js_harness) - content += " ".replace('{SCRIPT}', js_filename) + content += ' ' content += HTML_BOTTOM f.write(content) -def build_html(html_dir, js_dir, use_sync): +def build_html(html_dir, use_sync): print("Building HTML tests...") js_html_dir = os.path.join(html_dir, 'js') @@ -248,11 +263,15 @@ def process_args(): if js_dir is not None: ensure_empty_dir(js_dir) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(js_dir, d)) build_js(js_dir) if html_dir is not None: ensure_empty_dir(html_dir) - build_html(html_dir, js_dir, args.use_sync) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(html_dir, d)) + build_html(html_dir, args.use_sync) if front_dir is not None: ensure_empty_dir(front_dir) diff --git a/test/core/call_indirect.wast b/test/core/call_indirect.wast index ba267fea5f..cc26b1b044 100644 --- a/test/core/call_indirect.wast +++ b/test/core/call_indirect.wast @@ -1000,6 +1000,15 @@ "type mismatch" ) +;; call_indirect expects funcref type but receives externref +(assert_invalid + (module + (type (func)) + (table 10 externref) + (func $call-indirect (call_indirect (type 0) (i32.const 0))) + ) + "type mismatch" +) ;; Unbound type @@ -1018,6 +1027,20 @@ "unknown type" ) +;; pass very large number to call_indirect +(assert_invalid + (module + (type (func (param i32))) + (table 1 funcref) + (func $conditional-dangling-type + (if (i32.const 1) + (then (call_indirect (type 0xffffffff) (i32.const 0))) + ) + ) + ) + "unknown type" +) + ;; Unbound function in table