Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.

Commit 8b99683

Browse files
authored
Merge pull request #22 from WebAssembly/merge
Merge with upstream ref-types
2 parents e8be8cb + 4166bdb commit 8b99683

File tree

173 files changed

+10203
-3995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+10203
-3995
lines changed

.travis.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
language: c++
21
language: python
32
python:
4-
- "2.7"
3+
- "3.7"
4+
dist: bionic
55

6-
sudo: on
7-
8-
before_install:
9-
- curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
10-
- echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
11-
- sudo apt-get update -qq
6+
addons:
7+
apt:
8+
sources:
9+
- sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main'
10+
key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg'
11+
packages:
12+
- ocaml
13+
- ocamlbuild
14+
- texlive-full
15+
- yarn
1216

1317
install:
14-
- ./interpreter/meta/travis/install-ocaml.sh
15-
- sudo pip install sphinx==1.7.9
16-
- sudo apt-get install texlive-full yarn
18+
- pip install Sphinx==2.4.4
1719
- git clone https://github.com/tabatkins/bikeshed.git
1820
- pip install --editable $PWD/bikeshed
1921
- bikeshed update

document/core/Makefile

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,10 @@ STATICDIR = _static
1010
DOWNLOADDIR = _download
1111
NAME = WebAssembly
1212

13-
# Hack until we have moved to more recent Sphinx.
14-
OLDMATHJAX = https://cdn.mathjax.org/mathjax/latest/MathJax.js
15-
NEWMATHJAX = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js
16-
1713
# Internal variables.
1814
PAPEROPT_a4 = -D latex_paper_size=a4
1915
PAPEROPT_letter = -D latex_paper_size=letter
20-
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
16+
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(SPHINXOPTS) .
2117
# the i18n builder cannot share the environment and doctrees with the others
2218
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
2319

@@ -111,16 +107,10 @@ html:
111107
do \
112108
sed s:BASEDIR:.:g <$$file >$$file.out; \
113109
mv -f $$file.out $$file; \
114-
sed s~$(OLDMATHJAX)~$(NEWMATHJAX)~g <$$file >$$file.out; \
115-
mv -f $$file.out $$file; \
116110
done
117111
for file in `ls $(BUILDDIR)/html/*/*.html`; \
118112
do \
119113
sed s:BASEDIR:..:g <$$file >$$file.out; \
120-
sed 's;<body; <script type="text/javascript">MathJax.Hub.Config({TeX: {MAXBUFFER: 30*1024}})</script><body;' \
121-
<$$file.out >$$file; \
122-
rm -f $$file.out; \
123-
sed s~$(OLDMATHJAX)~$(NEWMATHJAX)~g <$$file >$$file.out; \
124114
mv -f $$file.out $$file; \
125115
done
126116
@echo

document/core/appendix/algorithm.rst

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,16 @@ A simple subtyping check can be defined on these types.
2626

2727
.. code-block:: pseudo
2828
29-
type val_type = I32 | I64 | F32 | F64 | Anyref | Funcref | Nullref | Bot
29+
type val_type = I32 | I64 | F32 | F64 | Funcref | Externref | Bot
3030
3131
func is_num(t : val_type) : bool =
3232
return t = I32 || t = I64 || t = F32 || t = F64 || t = Bot
3333
3434
func is_ref(t : val_type) : bool =
35-
return t = Anyref || t = Funcref || t = Nullref || t = Bot
35+
return t = Funcref || t = Externref || t = Bot
3636
3737
func matches(t1 : val_type, t2 : val_type) : bool =
38-
return t1 = t2 || t1 = Bot ||
39-
(t1 = Nullref && is_ref(t2)) || (is_ref(t1) && t2 = Anyref)
38+
return t1 = t2 || t1 = Bot
4039
4140
The algorithm uses two separate stacks: the *value stack* and the *control stack*.
4241
The former tracks the :ref:`types <syntax-valtype>` of operand values on the :ref:`stack <stack>`,
@@ -48,19 +47,16 @@ the latter surrounding :ref:`structured control instructions <syntax-instr-contr
4847
4948
type ctrl_stack = stack(ctrl_frame)
5049
type ctrl_frame = {
51-
label_types : list(val_type)
50+
opcode : opcode
51+
start_types : list(val_type)
5252
end_types : list(val_type)
5353
height : nat
5454
unreachable : bool
5555
}
5656
5757
For each value, the value stack records its :ref:`value type <syntax-valtype>`.
5858

59-
For each entered block, the control stack records a *control frame* with the type of the associated :ref:`label <syntax-label>` (used to type-check branches), the result type of the block (used to check its result), the height of the operand stack at the start of the block (used to check that operands do not underflow the current block), and a flag recording whether the remainder of the block is unreachable (used to handle :ref:`stack-polymorphic <polymorphism>` typing after branches).
60-
61-
.. note::
62-
In the presentation of this algorithm, multiple values are supported for the :ref:`result types <syntax-resulttype>` classifying blocks and labels.
63-
With the current version of WebAssembly, the :code:`list` could be simplified to an optional value.
59+
For each entered block, the control stack records a *control frame* with the originating opcode, the types on the top of the operand stack at the start and end of the block (used to check its result as well as branches), the height of the operand stack at the start of the block (used to check that operands do not underflow the current block), and a flag recording whether the remainder of the block is unreachable (used to handle :ref:`stack-polymorphic <polymorphism>` typing after branches).
6460

6561
For the purpose of presenting the algorithm, the operand and control stacks are simply maintained as global variables:
6662

@@ -76,7 +72,7 @@ However, these variables are not manipulated directly by the main checking funct
7672
func push_val(type : val_type) =
7773
vals.push(type)
7874
79-
func pop_val() : val_type =
75+
func pop_val() : val_type | Unknown =
8076
if (vals.size() = ctrls[0].height && ctrls[0].unreachable) return Bot
8177
error_if(vals.size() = ctrls[0].height)
8278
return vals.pop()
@@ -114,17 +110,21 @@ The control stack is likewise manipulated through auxiliary functions:
114110

115111
.. code-block:: pseudo
116112
117-
func push_ctrl(label : list(val_type), out : list(val_type)) =
118-
 let frame = ctrl_frame(label, out, vals.size(), false)
113+
func push_ctrl(opcode : opcode, in : list(val_type), out : list(val_type)) =
114+
 let frame = ctrl_frame(opcode, in, out, vals.size(), false)
119115
  ctrls.push(frame)
116+
push_vals(in)
120117
121-
func pop_ctrl() : list(val_type) =
118+
func pop_ctrl() : ctrl_frame =
122119
 error_if(ctrls.is_empty())
123120
 let frame = ctrls[0]
124121
  pop_vals(frame.end_types)
125122
  error_if(vals.size() =/= frame.height)
126123
ctrls.pop()
127-
  return frame.end_types
124+
  return frame
125+
126+
func label_types(frame : ctrl_frame) : list(val_types) =
127+
return (if frame.opcode == loop then frame.start_types else frame.end_types)
128128
129129
func unreachable() =
130130
  vals.resize(ctrls[0].height)
@@ -137,6 +137,8 @@ Popping a frame first checks that the control stack is not empty.
137137
It then verifies that the operand stack contains the right types of values expected at the end of the exited block and pops them off the operand stack.
138138
Afterwards, it checks that the stack has shrunk back to its initial height.
139139

140+
The type of the :ref:`label <syntax-label>` associated with a control frame is either that of the stack at the start or the end of the frame, determined by the opcode that it originates from.
141+
140142
Finally, the current frame can be marked as unreachable.
141143
In that case, all existing operand types are purged from the value stack, in order to allow for the :ref:`stack-polymorphism <polymorphism>` logic in :code:`pop_val` to take effect.
142144

@@ -187,44 +189,48 @@ Other instructions are checked in a similar manner.
187189
   case (unreachable)
188190
      unreachable()
189191
190-
case (block t*)
191-
push_ctrl([t*], [t*])
192+
case (block t1*->t2*)
193+
pop_vals([t1*])
194+
push_ctrl(block, [t1*], [t2*])
192195
193-
case (loop t*)
194-
push_ctrl([], [t*])
196+
case (loop t1*->t2*)
197+
pop_vals([t1*])
198+
push_ctrl(loop, [t1*], [t2*])
195199
196-
case (if t*)
200+
case (if t1*->t2*)
197201
pop_val(I32)
198-
push_ctrl([t*], [t*])
202+
pop_vals([t1*])
203+
push_ctrl(if, [t1*], [t2*])
199204
200205
case (end)
201-
let results = pop_ctrl()
202-
push_vals(results)
206+
let frame = pop_ctrl()
207+
push_vals(frame.end_types)
203208
204209
case (else)
205-
let results = pop_ctrl()
206-
push_ctrl(results, results)
210+
let frame = pop_ctrl()
211+
error_if(frame.opcode =/= if)
212+
push_ctrl(else, frame.start_types, frame.end_types)
207213
208214
case (br n)
209215
     error_if(ctrls.size() < n)
210-
      pop_vals(ctrls[n].label_types)
216+
      pop_vals(label_types(ctrls[n]))
211217
      unreachable()
212218
213219
case (br_if n)
214220
     error_if(ctrls.size() < n)
215221
pop_val(I32)
216-
      pop_vals(ctrls[n].label_types)
217-
      push_vals(ctrls[n].label_types)
222+
      pop_vals(label_types(ctrls[n]))
223+
      push_vals(label_types(ctrls[n]))
218224
219225
   case (br_table n* m)
220226
pop_val(I32)
221227
      error_if(ctrls.size() < m)
222-
let arity = ctrls[m].label_types.size()
228+
let arity = label_types(ctrls[m]).size()
223229
      foreach (n in n*)
224230
        error_if(ctrls.size() < n)
225-
        error_if(ctrls[n].label_types.size() =/= arity)
226-
push_vals(pop_vals(ctrls[n].label_types))
227-
pop_vals(ctrls[m].label_types)
231+
        error_if(label_types(ctrls[n]).size() =/= arity)
232+
push_vals(pop_vals(label_types(ctrls[n])))
233+
      pop_vals(label_types(ctrls[m]))
228234
      unreachable()
229235
230236
.. note::

document/core/appendix/implementation.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ An implementation may impose restrictions on the following dimensions of a modul
4343
* the number of :ref:`exports <syntax-export>` from a :ref:`module <syntax-module>`
4444
* the number of parameters in a :ref:`function type <syntax-functype>`
4545
* the number of results in a :ref:`function type <syntax-functype>`
46+
* the number of parameters in a :ref:`block type <syntax-blocktype>`
47+
* the number of results in a :ref:`block type <syntax-blocktype>`
4648
* the number of :ref:`locals <syntax-local>` in a :ref:`function <syntax-func>`
4749
* the size of a :ref:`function <syntax-func>` body
4850
* the size of a :ref:`structured control instruction <syntax-instr-control>`

0 commit comments

Comments
 (0)