You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: document/README.md
+95Lines changed: 95 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,3 +21,98 @@ To build everything and update [webassembly.github.io/spec](https://webassembly.
21
21
make publish
22
22
```
23
23
Please make sure to only use that once a change has approval.
24
+
25
+
## Step by step guide to building the spec
26
+
27
+
### Prerequisites
28
+
29
+
You will need `python3.7`, and `pip`. `pip` should come with Python, if not follow [these installation instructions for `pip`](https://pip.pypa.io/en/stable/installing/), or check your system package manager for `pip3`.
30
+
31
+
> Important: you will need the version of pip that works with `python3.7`.
32
+
33
+
34
+
Use something like [`pipenv`](https://pipenv.pypa.io/) to keep your system installation of Python clean.
35
+
36
+
```
37
+
pip install pipenv
38
+
pipenv --python 3.7
39
+
pipenv shell
40
+
```
41
+
42
+
Install Python dependencies:
43
+
44
+
```
45
+
pipenv install Sphinx==3.5.2
46
+
```
47
+
48
+
### Checking out the repository
49
+
50
+
Make sure this repository was cloned with `--recursive`:
If you have already cloned but without `--recursive`, you can delete and re-clone, or `cd` into `spec` and run:
57
+
58
+
```
59
+
git submodule update --init --recursive
60
+
```
61
+
62
+
The rest of these instructions assume you are in the directory where is README is:
63
+
64
+
```
65
+
cd spec/document
66
+
```
67
+
68
+
### Building the multi-page HTML document
69
+
70
+
You can now build the [multi-page html document](https://webassembly.github.io/spec/core/):
71
+
72
+
```
73
+
make -C core html
74
+
```
75
+
76
+
### Building the single-page HTML document
77
+
78
+
To build the [single-page W3C version](https://webassembly.github.io/spec/core/bikeshed/), there are more dependencies to install. First, get [Bikeshed](https://github.com/tabatkins/bikeshed):
You will also need `npm` and `yarn` for all the LaTeX goodness. `npm` might already be available on your system, you can also use something like [`nvm`](https://github.com/nvm-sh/nvm) to prevent messing with system packages:
88
+
89
+
```
90
+
npm install -g yarn
91
+
cd document
92
+
make -C core bikeshed
93
+
```
94
+
95
+
### Building the PDF
96
+
97
+
To build the [PDF](https://webassembly.github.io/spec/core/_download/WebAssembly.pdf), you will need `texlive-full`, install it using your system package manager:
98
+
99
+
```
100
+
apt install texlive-full
101
+
make -C core pdf
102
+
```
103
+
104
+
### Building the JavaScript Embedding API
105
+
106
+
To build the [JavaScript Embedding API](https://webassembly.github.io/spec/js-api/index.html), you will need `bikeshed` as describe in the section [Building the single-page HTML document](#building-the-single-page-html-document):
107
+
108
+
```
109
+
make -C js-api
110
+
```
111
+
112
+
### Building the Web Embedding API
113
+
114
+
To build the [Web Embedding API](https://webassembly.github.io/spec/web-api/index.html), you will need `bikeshed` as describe in the section [Building the single-page HTML document](#building-the-single-page-html-document):
return t = I32 || t = I64 || t = F32 || t = F64 || t = Unknown
32
+
33
+
func is_ref(t : val_type | Unknown) : bool =
34
+
return t = Funcref || t = Externref || t = Unknown
35
+
36
+
The algorithm uses two separate stacks: the *value stack* and the *control stack*.
25
37
The former tracks the :ref:`types <syntax-valtype>` of operand values on the :ref:`stack <stack>`,
26
38
the latter surrounding :ref:`structured control instructions <syntax-instr-control>` and their associated :ref:`blocks <syntax-instr-control>`.
27
39
28
40
.. code-block:: pseudo
29
41
30
-
type val_type = I32 | I64 | F32 | F64
31
-
32
-
type opd_stack = stack(val_type | Unknown)
42
+
type val_stack = stack(val_type | Unknown)
33
43
34
44
type ctrl_stack = stack(ctrl_frame)
35
45
type ctrl_frame = {
@@ -40,79 +50,82 @@ the latter surrounding :ref:`structured control instructions <syntax-instr-contr
40
50
unreachable : bool
41
51
}
42
52
43
-
For each value, the operand stack records its :ref:`value type <syntax-valtype>`, or :code:`Unknown` when the type is not known.
53
+
For each value, the value stack records its :ref:`value type <syntax-valtype>`, or :code:`Unknown` when the type is not known.
44
54
45
55
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).
46
56
47
57
For the purpose of presenting the algorithm, the operand and control stacks are simply maintained as global variables:
48
58
49
59
.. code-block:: pseudo
50
60
51
-
var opds : opd_stack
61
+
var vals : val_stack
52
62
var ctrls : ctrl_stack
53
63
54
64
However, these variables are not manipulated directly by the main checking function, but through a set of auxiliary functions:
55
65
56
66
.. code-block:: pseudo
57
67
58
-
func push_opd(type : val_type | Unknown) =
59
-
opds.push(type)
68
+
func push_val(type : val_type | Unknown) =
69
+
vals.push(type)
60
70
61
-
func pop_opd() : val_type | Unknown =
62
-
if (opds.size() = ctrls[0].height && ctrls[0].unreachable) return Unknown
63
-
error_if(opds.size() = ctrls[0].height)
64
-
return opds.pop()
71
+
func pop_val() : val_type | Unknown =
72
+
if (vals.size() = ctrls[0].height && ctrls[0].unreachable) return Unknown
return (if frame.opcode == loop then frame.start_types else frame.end_types)
113
126
114
127
func unreachable() =
115
-
opds.resize(ctrls[0].height)
128
+
vals.resize(ctrls[0].height)
116
129
ctrls[0].unreachable := true
117
130
118
131
Pushing a control frame takes the types of the label and result values.
@@ -125,7 +138,7 @@ Afterwards, it checks that the stack has shrunk back to its initial height.
125
138
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.
126
139
127
140
Finally, the current frame can be marked as unreachable.
128
-
In that case, all existing operand types are purged from the operand stack, in order to allow for the :ref:`stack-polymorphism <polymorphism>` logic in :code:`pop_opd` to take effect.
141
+
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.
129
142
130
143
.. note::
131
144
Even with the unreachable flag set, consecutive operands are still pushed to and popped from the operand stack.
@@ -150,38 +163,46 @@ Other instructions are checked in a similar manner.
0 commit comments