WebAssembly Specification Release 1.1 (Draft 2021-12-18) - page 12

 

  Главная      Manuals     WebAssembly Specification Release 1.1 (Draft 2021-12-18)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     10      11      12      13     ..

 

 

 

WebAssembly Specification Release 1.1 (Draft 2021-12-18) - page 12

 

 

5.5.13 Code Section

The

code section

has the id 10. It decodes into a vector of

code

entries that are pairs of

value type

vectors and

expressions

They represent the

locals

and

body

field of the

functions

in the

funcs

component of a

module

The

type

fields of the respective functions are encoded separately in the

function section

.

The encoding of each code entry consists of

• the

u32

size

of the function code in bytes,

• the actual

function code

, which in turn consists of

the declaration of

locals

,

the function

body

as an

expression

.

Local declarations are compressed into a vector whose entries consist of

• a

u32

count

,

• a

value type

,

denoting

count

locals of the same value type.

codesec

::=

code

*

:

section

10

(

vec

(

code

))

code

*

code

::=

size

:

u32

code

:

func

code

(

if

size

=

||

func

||

)

func

::=

(

𝑡

*

)

*

:

vec

(

locals

)

𝑒

:

expr

concat

((

𝑡

*

)

*

)

, 𝑒

*

(

if

|

concat

((

𝑡

*

)

*

)

|

<

2

32

)

locals

::=

𝑛

:

u32

𝑡

:

valtype

𝑡

𝑛

Here,

code

ranges over pairs

(

valtype

*

,

expr

)

. The meta function

concat

((

𝑡

*

)

*

)

concatenates all sequences

𝑡

*

𝑖

in

(

𝑡

*

)

*

. Any code for which the length of the resulting sequence is out of bounds of the maximum size of a

vector

is malformed.

Note:

Like with

sections

the code

size

is not needed for decoding, but can be used to skip functions when

navigating through a binary. The module is malformed if a size does not match the length of the respective function

code.

5.5.14 Data Section

The

data section

has the id 11. It decodes into a vector of

data segments

that represent the

datas

component of a

module

.

datasec

::=

seg

*

:

section

11

(

vec

(

data

))

seg

data

::=

0x00

𝑒

:

expr

𝑏

*

:

vec

(

byte

)

{

init

𝑏

*

,

mode active

{

memory

0

,

offset

𝑒

}}

|

0x01

𝑏

*

:

vec

(

byte

)

{

init

𝑏

*

,

mode passive

}

|

0x02

𝑥

:

memidx

𝑒

:

expr

𝑏

*

:

vec

(

byte

)

{

init

𝑏

*

,

mode active

{

memory

𝑥,

offset

𝑒

}}

Note:

The initial byte can be interpreted as a bitfield. Bit 0 indicates a passive segment, bit 1 indicates the presence

of an explicit memory index for an active segment.
In the current version of WebAssembly, at most one memory may be defined or imported in a single module, so

all valid

active

data segments have a

memory

value of

0

.

5.5. Modules

151

5.5.15 Data Count Section

The

data count section

has the id 12. It decodes into an optional

u32

that represents the number of

data segments

in the

data section

If this count does not match the length of the data segment vector, the module is malformed.

datacountsec

::=

n

?

:

section

12

(

u32

)

n

?

Note:

The data count section is used to simplify single-pass validation. Since the data section occurs after the

code section, the

memory

.

init

and

data

.

drop

instructions would not be able to check whether the data segment

index is valid until the data section is read. The data count section occurs before the code section, so a single-pass

validator can use this count instead of deferring validation.

5.5.16 Modules

The encoding of a

module

starts with a preamble containing a 4-byte magic number (the string ‘

0asm

’) and a

version field. The current version of the WebAssembly binary format is 1.
The preamble is followed by a sequence of

sections

.

Custom sections

may be inserted at any place in this sequence,

while other sections must occur at most once and in the prescribed order. All sections can be empty.
The lengths of vectors produced by the (possibly empty)

function

and

code

section must match up.

Similarly, the optional data count must match the length of the

data segment

vector. Furthermore, it must be present

152

Chapter 5. Binary Format

if any

𝑑𝑎𝑡𝑎𝑖𝑛𝑑𝑒𝑥 < 𝑠𝑦𝑛𝑡𝑎𝑥

𝑑𝑎𝑡𝑎𝑖𝑑𝑥 >

occurs in the code section.

magic

::=

0x00 0x61 0x73 0x6D

version

::=

0x01 0x00 0x00 0x00

module

::=

magic
version
customsec

*

functype

*

:

typesec

customsec

*

import

*

:

importsec

customsec

*

typeidx

𝑛

:

funcsec

customsec

*

table

*

:

tablesec

customsec

*

mem

*

:

memsec

customsec

*

global

*

:

globalsec

customsec

*

export

*

:

exportsec

customsec

*

start

?

:

startsec

customsec

*

elem

*

:

elemsec

customsec

*

𝑚

?

:

datacountsec

customsec

*

code

𝑛

:

codesec

customsec

*

data

𝑚

:

datasec

customsec

*

{

types

functype

*

,

funcs

func

𝑛

,

tables

table

*

,

mems

mem

*

,

globals

global

*

,

elems

elem

*

,

datas

data

𝑚

,

start

start

?

,

imports

import

*

,

exports

export

*

}

(

if

𝑚

?

̸

=

𝜖

dataidx

(

code

𝑛

) =

)

where for each

𝑡

*

𝑖

, 𝑒

𝑖

in

code

𝑛

,

func

𝑛

[

𝑖

] =

{

type

typeidx

𝑛

[

𝑖

]

,

locals

𝑡

*

𝑖

,

body

𝑒

𝑖

}

)

Note:

The version of the WebAssembly binary format may increase in the future if backward-incompatible

changes have to be made to the format. However, such changes are expected to occur very infrequently, if ever. The

binary format is intended to be forward-compatible, such that future extensions can be made without incrementing

its version.

5.5. Modules

153

154

Chapter 5. Binary Format

CHAPTER

6

Text Format

6.1 Conventions

The textual format for WebAssembly

modules

is a rendering of their

abstract syntax

into

S-expressions

35

.

Like the

binary format

the text format is defined by an

attribute grammar

. A text string is a well-formed description

of a module if and only if it is generated by the grammar. Each production of this grammar has at most one

synthesized attribute: the abstract syntax that the respective character sequence expresses. Thus, the attribute

grammar implicitly defines a

parsing

function. Some productions also take a

context

as an inherited attribute that

records bound

identifiers

.

Except for a few exceptions, the core of the text grammar closely mirrors the grammar of the abstract syntax.

However, it also defines a number of

abbreviations

that are “syntactic sugar” over the core syntax.

The recommended extension for files containing WebAssembly modules in text format is “

.

wat

”. Files with this

extension are assumed to be encoded in UTF-8, as per

Unicode

36

(Section 2.5).

6.1.1 Grammar

The following conventions are adopted in defining grammar rules of the text format. They mirror the conventions

used for

abstract syntax

and for the

binary format

In order to distinguish symbols of the textual syntax from

symbols of the abstract syntax,

typewriter

font is adopted for the former.

• Terminal symbols are either literal strings of characters enclosed in quotes or expressed as

Unicode

37

scalar

values: ‘

module

’,

U+0A

. (All characters written literally are unambiguously drawn from the 7-bit

ASCII

38

subset of Unicode.)

• Nonterminal symbols are written in typewriter font:

valtype

,

instr

.

𝑇

𝑛

is a sequence of

𝑛

0

iterations of

𝑇

.

𝑇

*

is a possibly empty sequence of iterations of

𝑇

. (This is a shorthand for

𝑇

𝑛

used where

𝑛

is not relevant.)

𝑇

+

is a sequence of one or more iterations of

𝑇

. (This is a shorthand for

𝑇

𝑛

where

𝑛

1

.)

𝑇

?

is an optional occurrence of

𝑇

. (This is a shorthand for

𝑇

𝑛

where

𝑛

1

.)

35

https://en.wikipedia.org/wiki/S-expression

36

https://www.unicode.org/versions/latest/

37

https://www.unicode.org/versions/latest/

38

https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS+4-1986%5bR2012%5d

155

𝑥

:

𝑇

denotes the same language as the nonterminal

𝑇

, but also binds the variable

𝑥

to the attribute synthesized

for

𝑇

.

• Productions are written

sym

::=

𝑇

1

𝐴

1

|

. . .

|

𝑇

𝑛

𝐴

𝑛

, where each

𝐴

𝑖

is the attribute that is synthesized

for

sym

in the given case, usually from attribute variables bound in

𝑇

𝑖

.

• Some productions are augmented by side conditions in parentheses, which restrict the applicability of the

production. They provide a shorthand for a combinatorial expansion of the production into many separate

cases.

• If the same meta variable or non-terminal symbol appears multiple times in a production (in the syntax or in

an attribute), then all those occurrences must have the same instantiation.

• A distinction is made between

lexical

and

syntactic

productions. For the latter, arbitrary

white space

is

allowed in any place where the grammar contains spaces. The productions defining

lexical syntax

and the

syntax of

values

are considered lexical, all others are syntactic.

Note:

For example, the

textual grammar

for

number types

is given as follows:

numtype

::=

i32

i32

|

i64

i64

|

f32

f32

|

f64

f64

The

textual grammar

for

limits

is defined as follows:

limits

::=

𝑛

:

u32

{

min

𝑛,

max

𝜖

}

|

𝑛

:

u32

𝑚

:

u32

{

min

𝑛,

max

𝑚

}

The variables

𝑛

and

𝑚

name the attributes of the respective

u32

nonterminals, which in this case are the actual

unsigned integers

those parse into. The attribute of the complete production then is the abstract syntax for the limit,

expressed in terms of the former values.

6.1.2 Abbreviations

In addition to the core grammar, which corresponds directly to the

abstract syntax

the textual syntax also defines

a number of

abbreviations

that can be used for convenience and readability.

Abbreviations are defined by

rewrite rules

specifying their expansion into the core syntax:

abbreviation syntax

expanded syntax

These expansions are assumed to be applied, recursively and in order of appearance, before applying the core

grammar rules to construct the abstract syntax.

6.1.3 Contexts

The text format allows the use of symbolic

identifiers

in place of

indices

To resolve these identifiers into concrete

indices, some grammar production are indexed by an

identifier context

𝐼

as a synthesized attribute that records the

declared identifiers in each

index space

In addition, the context records the types defined in the module, so that

parameter

indices can be computed for

functions

.

156

Chapter 6. Text Format

It is convenient to define identifier contexts as

records

𝐼

with abstract syntax as follows:

𝐼

::=

{

types

(

id

?

)

*

,

funcs

(

id

?

)

*

,

tables

(

id

?

)

*

,

mems

(

id

?

)

*

,

globals

(

id

?

)

*

,

elem

(

id

?

)

*

,

data

(

id

?

)

*

,

locals

(

id

?

)

*

,

labels

(

id

?

)

*

,

typedefs

functype

*

}

For each index space, such a context contains the list of

identifiers

assigned to the defined indices. Unnamed indices

are associated with empty (

𝜖

) entries in these lists.

An identifier context is

well-formed

if no index space contains duplicate identifiers.

Conventions

To avoid unnecessary clutter, empty components are omitted when writing out identifier contexts. For example,

the record

{}

is shorthand for an

identifier context

whose components are all empty.

6.1.4 Vectors

Vectors

are written as plain sequences, but with a restriction on the length of these sequence.

vec

(

A

)

::=

(

𝑥

:

A

)

𝑛

𝑥

𝑛

(

if

𝑛 <

2

32

)

6.2 Lexical Format

6.2.1 Characters

The text format assigns meaning to

source text

, which consists of a sequence of

characters

. Characters are assumed

to be represented as valid

Unicode

39

(Section 2.4)

scalar values

.

source

::=

char

*

char

::=

U+00

|

. . .

|

U+D7FF

|

U+E000

|

. . .

|

U+10FFFF

Note:

While source text may contain any Unicode character in

comments

or

string

literals, the rest of the grammar

is formed exclusively from the characters supported by the 7-bit

ASCII

40

subset of Unicode.

39

https://www.unicode.org/versions/latest/

40

https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS+4-1986%5bR2012%5d

6.2. Lexical Format

157

6.2.2 Tokens

The character stream in the source text is divided, from left to right, into a sequence of

tokens

, as defined by the

following grammar.

token

::=

keyword

|

u

𝑁

|

s

𝑁

|

f

𝑁

|

string

|

id

|

(

|

)

|

reserved

keyword

::=

(

a

|

. . .

|

z

)

idchar

*

(

if occurring as a literal terminal in the grammar

)

reserved

::=

idchar

+

Tokens are formed from the input character stream according to the

longest match

rule. That is, the next token

always consists of the longest possible sequence of characters that is recognized by the above lexical grammar.

Tokens can be separated by

white space

but except for strings, they cannot themselves contain whitespace.

The set of

keyword

tokens is defined implicitly, by all occurrences of a

terminal symbol

in literal form, such as

keyword

’, in a

syntactic

production of this chapter.

Any token that does not fall into any of the other categories is considered

reserved

, and cannot occur in source text.

Note:

The effect of defining the set of reserved tokens is that all tokens must be separated by either parentheses or

white space

For example, ‘

0

$

x

’ is a single reserved token. Consequently, it is not recognized as two separate tokens

0

’ and ‘

$

x

’, but instead disallowed. This property of tokenization is not affected by the fact that the definition of

reserved tokens overlaps with other token classes.

6.2.3 White Space

White space

is any sequence of literal space characters, formatting characters, or

comments

The allowed formatting

characters correspond to a subset of the

ASCII

41

format effectors

, namely,

horizontal tabulation

(

U+09

),

line feed

(

U+0A

), and

carriage return

(

U+0D

).

space

::=

(

‘ ’

|

format

|

comment

)

*

format

::=

U+09

|

U+0A

|

U+0D

The only relevance of white space is to separate

tokens

It is otherwise ignored.

6.2.4 Comments

A

comment

can either be a

line comment

, started with a double semicolon ‘

;;

’ and extending to the end of the line,

or a

block comment

, enclosed in delimiters ‘

(;

. . .

;)

’. Block comments can be nested.

comment

::=

linecomment

|

blockcomment

linecomment

::=

;;

linechar

*

(U+0A

|

eof

)

linechar

::=

𝑐

:

char

(

if

𝑐

̸

= U+0A)

blockcomment

::=

(;

blockchar

*

;)

blockchar

::=

𝑐

:

char

(

if

𝑐

̸

=

;

𝑐

̸

=

(

)

|

;

(

if the next character is not ‘

)

)

|

(

(

if the next character is not ‘

;

)

|

blockcomment

Here, the pseudo token

eof

indicates the end of the input. The

look-ahead

restrictions on the productions for

blockchar

disambiguate the grammar such that only well-bracketed uses of block comment delimiters are allowed.

Note:

Any formatting and control characters are allowed inside comments.

41

https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS+4-1986%5bR2012%5d

158

Chapter 6. Text Format

6.3 Values

The grammar productions in this section define

lexical syntax

, hence no

white space

is allowed.

6.3.1 Integers

All

integers

can be written in either decimal or hexadecimal notation. In both cases, digits can optionally be

separated by underscores.

sign

::=

𝜖

+

|

+

+

|

⇒ −

digit

::=

0

0

|

. . .

|

9

9

hexdigit

::=

𝑑

:

digit

𝑑

|

A

10

|

. . .

|

F

15

|

a

10

|

. . .

|

f

15

num

::=

𝑑

:

digit

𝑑

|

𝑛

:

num

‘_’

?

𝑑

:

digit

10

·

𝑛

+

𝑑

hexnum

::=

:

hexdigit

|

𝑛

:

hexnum

‘_’

?

:

hexdigit

16

·

𝑛

+

The allowed syntax for integer literals depends on size and signedness. Moreover, their value must lie within the

range of the respective type.

u

𝑁

::=

𝑛

:

num

𝑛

(

if

𝑛 <

2

𝑁

)

|

0x

𝑛

:

hexnum

𝑛

(

if

𝑛 <

2

𝑁

)

s

𝑁

::=

±

:

sign

𝑛

:

num

±

𝑛

(

if

2

𝑁

1

≤ ±

𝑛 <

2

𝑁

1

)

|

±

:

sign

0x

𝑛

:

hexnum

±

𝑛

(

if

2

𝑁

1

≤ ±

𝑛 <

2

𝑁

1

)

Uninterpreted integers

can be written as either signed or unsigned, and are normalized to unsigned in the abstract

syntax.

i

𝑁

::=

𝑛

:

u

𝑁

𝑛

|

𝑖

:

s

𝑁

𝑛

(

if

𝑖

=

signed

(

𝑛

))

6.3.2 Floating-Point

Floating-point

values can be represented in either decimal or hexadecimal notation.

frac

::=

𝑑

:

digit

𝑑/

10

|

𝑑

:

digit

‘_’

?

𝑝

:

frac

(

𝑑

+

𝑝/

10)

/

10

hexfrac

::=

:

hexdigit

ℎ/

16

|

:

hexdigit

‘_’

?

𝑝

:

hexfrac

(

+

𝑝/

16)

/

16

float

::=

𝑝

:

num

.

?

𝑝

|

𝑝

:

num

.

𝑞

:

frac

𝑝

+

𝑞

|

𝑝

:

num

.

?

(

E

|

e

)

±

:

sign

𝑒

:

num

𝑝

·

10

±

𝑒

|

𝑝

:

num

.

𝑞

:

frac

(

E

|

e

)

±

:

sign

𝑒

:

num

(

𝑝

+

𝑞

)

·

10

±

𝑒

hexfloat

::=

0x

𝑝

:

hexnum

.

?

𝑝

|

0x

𝑝

:

hexnum

.

𝑞

:

hexfrac

𝑝

+

𝑞

|

0x

𝑝

:

hexnum

.

?

(

P

|

p

)

±

:

sign

𝑒

:

num

𝑝

·

2

±

𝑒

|

0x

𝑝

:

hexnum

.

𝑞

:

hexfrac

(

P

|

p

)

±

:

sign

𝑒

:

num

(

𝑝

+

𝑞

)

·

2

±

𝑒

The value of a literal must not lie outside the representable range of the corresponding

IEEE 754-2019

42

type (that

is, a numeric value must not overflow to

±

infinity), but it may be

rounded

to the nearest representable value.

42

https://ieeexplore.ieee.org/document/8766229

6.3. Values

159

Note:

Rounding can be prevented by using hexadecimal notation with no more significant bits than supported by

the required type.

Floating-point values may also be written as constants for

infinity

or

canonical NaN

(

not a number

). Furthermore,

arbitrary NaN values may be expressed by providing an explicit payload value.

f

𝑁

::=

±

:

sign

𝑧

:

f

𝑁

mag

±

𝑧

f

𝑁

mag

::=

𝑧

:

float

float

𝑁

(

𝑧

)

(

if

float

𝑁

(

𝑧

)

̸

=

±∞

)

|

𝑧

:

hexfloat

float

𝑁

(

𝑧

)

(

if

float

𝑁

(

𝑧

)

̸

=

±∞

)

|

inf

|

nan

nan

(2

signif

(

𝑁

)

1

)

|

nan

:

0x

𝑛

:

hexnum

nan

(

𝑛

)

(

if

1

𝑛 <

2

signif

(

𝑁

)

)

6.3.3 Strings

Strings

denote sequences of bytes that can represent both textual and binary data. They are enclosed in quotation

marks and may contain any character other than

ASCII

43

control characters, quotation marks (‘

’), or backslash

(‘

’), except when expressed with an

escape sequence

.

string

::=

(

𝑏

*

:

stringelem

)

*

concat

((

𝑏

*

)

*

)

(

if

|

concat

((

𝑏

*

)

*

)

|

<

2

32

)

stringelem

::=

𝑐

:

stringchar

utf8

(

𝑐

)

|

𝑛

:

hexdigit

𝑚

:

hexdigit

16

·

𝑛

+

𝑚

Each character in a string literal represents the byte sequence corresponding to its UTF-8

Unicode

44

(Section 2.5)

encoding, except for hexadecimal escape sequences ‘

ℎℎ

’, which represent raw bytes of the respective value.

stringchar

::=

𝑐

:

char

𝑐

(

if

𝑐

U+20

𝑐

̸

= U+7F

𝑐

̸

=

𝑐

̸

=

)

|

t

U+09

|

n

U+0A

|

r

U+0D

|

U+22

|

U+27

|

∖∖

U+5C

|

u

{

𝑛

:

hexnum

}

U+(n)

(

if

𝑛 <

0xD800

0xE000

𝑛 <

0x110000

)

6.3.4 Names

Names

are strings denoting a literal character sequence. A name string must form a valid UTF-8 encoding as

defined by

Unicode

45

(Section 2.5) and is interpreted as a string of Unicode scalar values.

name

::=

𝑏

*

:

string

𝑐

*

(

if

𝑏

*

=

utf8

(

𝑐

*

))

Note:

Presuming the source text is itself encoded correctly, strings that do not contain any uses of hexadecimal

byte escapes are always valid names.

43

https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS+4-1986%5bR2012%5d

44

https://www.unicode.org/versions/latest/

45

https://www.unicode.org/versions/latest/

160

Chapter 6. Text Format

6.3.5 Identifiers

Indices

can be given in both numeric and symbolic form. Symbolic

identifiers

that stand in lieu of indices start

with ‘

$

’, followed by any sequence of printable

ASCII

46

characters that does not contain a space, quotation mark,

comma, semicolon, or bracket.

id

::=

$

idchar

+

idchar

::=

0

|

. . .

|

9

|

A

|

. . .

|

Z

|

a

|

. . .

|

z

|

!

|

#

|

$

|

%

|

&

|

|

*

|

+

|

|

.

|

/

|

:

|

<

|

=

|

>

|

?

|

@

|

|

^

|

‘_’

|

`

|

|

|

~

Conventions

The expansion rules of some abbreviations require insertion of a

fresh

identifier. That may be any syntactically

valid identifier that does not already occur in the given source text.

6.4 Types

6.4.1 Number Types

numtype

::=

i32

i32

|

i64

i64

|

f32

f32

|

f64

f64

6.4.2 Vector Types

vectype

::=

v128

v128

6.4.3 Reference Types

reftype

::=

funcref

funcref

|

externref

externref

heaptype

::=

func

funcref

|

extern

externref

6.4.4 Value Types

valtype

::=

𝑡

:

numtype

𝑡

|

𝑡

:

vectype

𝑡

|

𝑡

:

reftype

𝑡

46

https://webstore.ansi.org/RecordDetail.aspx?sku=INCITS+4-1986%5bR2012%5d

6.4. Types

161

6.4.5 Function Types

functype

::=

(

’ ‘

func

𝑡

*

1

:

vec

(

param

)

𝑡

*

2

:

vec

(

result

)

)

[

𝑡

*

1

]

[

𝑡

*

2

]

param

::=

(

’ ‘

param

id

?

𝑡

:

valtype

)

𝑡

result

::=

(

’ ‘

result

𝑡

:

valtype

)

𝑡

Abbreviations

Multiple anonymous parameters or results may be combined into a single declaration:

(

’ ‘

param

valtype

*

)

(

(

’ ‘

param

valtype

)

)

*

(

’ ‘

result

valtype

*

)

(

(

’ ‘

result

valtype

)

)

*

6.4.6 Limits

limits

::=

𝑛

:

u32

{

min

𝑛,

max

𝜖

}

|

𝑛

:

u32

𝑚

:

u32

{

min

𝑛,

max

𝑚

}

6.4.7 Memory Types

memtype

::=

lim

:

limits

lim

6.4.8 Table Types

tabletype

::=

lim

:

limits

et

:

reftype

lim et

6.4.9 Global Types

globaltype

::=

𝑡

:

valtype

const

𝑡

|

(

’ ‘

mut

𝑡

:

valtype

)

var

𝑡

6.5 Instructions

Instructions are syntactically distinguished into

plain

and

structured

instructions.

instr

𝐼

::=

in

:

plaininstr

𝐼

in

|

in

:

blockinstr

𝐼

in

In addition, as a syntactic abbreviation, instructions can be written as S-expressions in

folded

form, to group them

visually.

162

Chapter 6. Text Format

6.5.1 Labels

Structured control instructions

can be annotated with a symbolic

label identifier

They are the only

symbolic

identifiers

that can be bound locally in an instruction sequence. The following grammar handles the corresponding

update to the

identifier context

by

composing

the context with an additional label entry.

label

𝐼

::=

𝑣

:

id

{

labels

𝑣

}

𝐼

(

if

𝑣 /

𝐼.

labels

)

|

𝜖

{

labels

(

𝜖

)

}

𝐼

Note:

The new label entry is inserted at the

beginning

of the label list in the identifier context. This effectively

shifts all existing labels up by one, mirroring the fact that control instructions are indexed relatively not absolutely.

6.5.2 Control Instructions

Structured control instructions

can bind an optional symbolic

label identifier

The same label identifier may op-

tionally be repeated after the corresponding

end

and

else

pseudo instructions, to indicate the matching delimiters.

Their

block type

is given as a

type use

analogous to the type of

functions

However, the special case of a type

use that is syntactically empty or consists of only a single

result

is not regarded as an

abbreviation

for an inline

function type

but is parsed directly into an optional

value type

.

blocktype

𝐼

::=

|

(

𝑡

:

result

)

?

𝑡

?

𝑥, 𝐼

:

typeuse

𝐼

𝑥

(

if

𝐼

=

{

locals

(

𝜖

)

*

}

)

blockinstr

𝐼

::=

block

𝐼

:

label

𝐼

bt

:

blocktype

𝐼

(

in

:

instr

𝐼

)

*

end

id

?

block

bt in

*

end

(

if

id

?

=

𝜖

id

?

=

label

)

|

loop

𝐼

:

label

𝐼

bt

:

blocktype

𝐼

(

in

:

instr

𝐼

)

*

end

id

?

loop

bt in

*

end

(

if

id

?

=

𝜖

id

?

=

label

)

|

if

𝐼

:

label

𝐼

bt

:

blocktype

𝐼

(

in

1

:

instr

𝐼

)

*

else

id

?

1

(

in

2

:

instr

𝐼

)

*

end

id

?

2

if

bt in

*

1

else

in

*

2

end

(

if

id

?

1

=

𝜖

id

?

1

=

label

,

id

?

2

=

𝜖

id

?

2

=

label

)

Note:

The side condition stating that the

identifier context

𝐼

must only contain unnamed entries in the rule for

typeuse

block types enforces that no identifier can be bound in any

param

declaration for a block type.

All other control instruction are represented verbatim.

plaininstr

𝐼

::=

unreachable

unreachable

|

nop

nop

|

br

𝑙

:

labelidx

𝐼

br

𝑙

|

br

_

if

𝑙

:

labelidx

𝐼

br

_

if

𝑙

|

br

_

table

𝑙

*

:

vec

(

labelidx

𝐼

)

𝑙

𝑁

:

labelidx

𝐼

br

_

table

𝑙

*

𝑙

𝑁

|

return

return

|

call

𝑥

:

funcidx

𝐼

call

𝑥

|

call

_

indirect

𝑥

:

tableidx

𝑦, 𝐼

:

typeuse

𝐼

call

_

indirect

𝑥 𝑦

(

if

𝐼

=

{

locals

(

𝜖

)

*

}

)

Note:

The side condition stating that the

identifier context

𝐼

must only contain unnamed entries in the rule for

call

_

indirect

enforces that no identifier can be bound in any

param

declaration appearing in the type annotation.

6.5. Instructions

163

Abbreviations

The ‘

else

’ keyword of an ‘

if

’ instruction can be omitted if the following instruction sequence is empty.

if

label blocktype instr

*

end

if

label blocktype instr

*

else

’ ‘

end

Also, for backwards compatibility, the table index to ‘

call

_

indirect

’ can be omitted, defaulting to

0

.

call

_

indirect

typeuse

call

_

indirect

0

typeuse

6.5.3 Reference Instructions

plaininstr

𝐼

::=

. . .

|

ref

.

null

𝑡

:

heaptype

ref

.

null

𝑡

|

ref

.

is

_

null

ref

.

is

_

null

|

ref

.

func

𝑥

:

funcidx

ref

.

func

𝑥

|

6.5.4 Parametric Instructions

plaininstr

𝐼

::=

. . .

|

drop

drop

|

select

((

𝑡

:

result

)

*

)

?

select

(

𝑡

*

)

?

6.5.5 Variable Instructions

plaininstr

𝐼

::=

. . .

|

local

.

get

𝑥

:

localidx

𝐼

local

.

get

𝑥

|

local

.

set

𝑥

:

localidx

𝐼

local

.

set

𝑥

|

local

.

tee

𝑥

:

localidx

𝐼

local

.

tee

𝑥

|

global

.

get

𝑥

:

globalidx

𝐼

global

.

get

𝑥

|

global

.

set

𝑥

:

globalidx

𝐼

global

.

set

𝑥

6.5.6 Table Instructions

plaininstr

𝐼

::=

. . .

|

table

.

get

𝑥

:

tableidx

𝐼

table

.

get

𝑥

|

table

.

set

𝑥

:

tableidx

𝐼

table

.

set

𝑥

|

table

.

size

𝑥

:

tableidx

𝐼

table

.

size

𝑥

|

table

.

grow

𝑥

:

tableidx

𝐼

table

.

grow

𝑥

|

table

.

fill

𝑥

:

tableidx

𝐼

table

.

fill

𝑥

|

table

.

copy

𝑥

:

tableidx

𝐼

𝑦

:

tableidx

𝐼

table

.

copy

𝑥 𝑦

|

table

.

init

𝑥

:

tableidx

𝐼

𝑦

:

elemidx

𝐼

table

.

init

𝑥 𝑦

|

elem

.

drop

𝑥

:

elemidx

𝐼

elem

.

drop

𝑥

164

Chapter 6. Text Format

Abbreviations

For backwards compatibility, all

𝑡𝑎𝑏𝑙𝑒𝑖𝑛𝑑𝑖𝑐𝑒𝑠 < 𝑠𝑦𝑛𝑡𝑎𝑥

𝑡𝑎𝑏𝑙𝑒𝑖𝑑𝑥 >

may be omitted from table instructions,

defaulting to

0

.

table

.

get

table

.

get

’ ‘

0

|

table

.

set

table

.

set

’ ‘

0

|

table

.

size

table

.

size

’ ‘

0

|

table

.

grow

table

.

grow

’ ‘

0

|

table

.

fill

table

.

fill

’ ‘

0

|

table

.

copy

table

.

copy

’ ‘

0

’ ‘

0

|

table

.

init

𝑥

:

elemidx

𝐼

table

.

init

’ ‘

0

𝑥

:

elemidx

𝐼

|

6.5.7 Memory Instructions

The offset and alignment immediates to memory instructions are optional. The offset defaults to

0

, the alignment

to the storage size of the respective memory access, which is its

natural alignment

. Lexically, an

offset

or

align

phrase is considered a single

keyword token

so no

white space

is allowed around the ‘

=

’.

memarg

𝑁

::=

𝑜

:

offset

𝑎

:

align

𝑁

{

align

𝑛,

offset

𝑜

}

(

if

𝑎

= 2

𝑛

)

offset

::=

offset

=

𝑜

:

u32

𝑜

|

𝜖

0

align

𝑁

::=

align

=

𝑎

:

u32

𝑎

|

𝜖

𝑁

plaininstr

𝐼

::=

. . .

|

i32

.

load

𝑚

:

memarg

4

i32

.

load

𝑚

|

i64

.

load

𝑚

:

memarg

8

i64

.

load

𝑚

|

f32

.

load

𝑚

:

memarg

4

f32

.

load

𝑚

|

f64

.

load

𝑚

:

memarg

8

f64

.

load

𝑚

|

i32

.

load8

_

s

𝑚

:

memarg

1

i32

.

load

8

_

s

𝑚

|

i32

.

load8

_

u

𝑚

:

memarg

1

i32

.

load

8

_

u

𝑚

|

i32

.

load16

_

s

𝑚

:

memarg

2

i32

.

load

16

_

s

𝑚

|

i32

.

load16

_

u

𝑚

:

memarg

2

i32

.

load

16

_

u

𝑚

|

i64

.

load8

_

s

𝑚

:

memarg

1

i64

.

load

8

_

s

𝑚

|

i64

.

load8

_

u

𝑚

:

memarg

1

i64

.

load

8

_

u

𝑚

|

i64

.

load16

_

s

𝑚

:

memarg

2

i64

.

load

16

_

s

𝑚

|

i64

.

load16

_

u

𝑚

:

memarg

2

i64

.

load

16

_

u

𝑚

|

i64

.

load32

_

s

𝑚

:

memarg

4

i64

.

load

32

_

s

𝑚

|

i64

.

load32

_

u

𝑚

:

memarg

4

i64

.

load

32

_

u

𝑚

|

i32

.

store

𝑚

:

memarg

4

i32

.

store

𝑚

|

i64

.

store

𝑚

:

memarg

8

i64

.

store

𝑚

|

f32

.

store

𝑚

:

memarg

4

f32

.

store

𝑚

|

f64

.

store

𝑚

:

memarg

8

f64

.

store

𝑚

|

i32

.

store8

𝑚

:

memarg

1

i32

.

store

8

𝑚

|

i32

.

store16

𝑚

:

memarg

2

i32

.

store

16

𝑚

|

i64

.

store8

𝑚

:

memarg

1

i64

.

store

8

𝑚

|

i64

.

store16

𝑚

:

memarg

2

i64

.

store

16

𝑚

|

i64

.

store32

𝑚

:

memarg

4

i64

.

store

32

𝑚

|

memory

.

size

memory

.

size

|

memory

.

grow

memory

.

grow

|

memory

.

fill

memory

.

fill

|

memory

.

copy

memory

.

copy

|

memory

.

init

𝑥

:

dataidx

𝐼

memory

.

init

𝑥

|

data

.

drop

𝑥

:

dataidx

𝐼

data

.

drop

𝑥

6.5. Instructions

165

6.5.8 Numeric Instructions

plaininstr

𝐼

::=

. . .

|

i32

.

const

𝑛

:

i32

i32

.

const

𝑛

|

i64

.

const

𝑛

:

i64

i64

.

const

𝑛

|

f32

.

const

𝑧

:

f32

f32

.

const

𝑧

|

f64

.

const

𝑧

:

f64

f64

.

const

𝑧

|

i32

.

clz

i32

.

clz

|

i32

.

ctz

i32

.

ctz

|

i32

.

popcnt

i32

.

popcnt

|

i32

.

add

i32

.

add

|

i32

.

sub

i32

.

sub

|

i32

.

mul

i32

.

mul

|

i32

.

div

_

s

i32

.

div

_

s

|

i32

.

div

_

u

i32

.

div

_

u

|

i32

.

rem

_

s

i32

.

rem

_

s

|

i32

.

rem

_

u

i32

.

rem

_

u

|

i32

.

and

i32

.

and

|

i32

.

or

i32

.

or

|

i32

.

xor

i32

.

xor

|

i32

.

shl

i32

.

shl

|

i32

.

shr

_

s

i32

.

shr

_

s

|

i32

.

shr

_

u

i32

.

shr

_

u

|

i32

.

rotl

i32

.

rotl

|

i32

.

rotr

i32

.

rotr

|

i64

.

clz

i64

.

clz

|

i64

.

ctz

i64

.

ctz

|

i64

.

popcnt

i64

.

popcnt

|

i64

.

add

i64

.

add

|

i64

.

sub

i64

.

sub

|

i64

.

mul

i64

.

mul

|

i64

.

div

_

s

i64

.

div

_

s

|

i64

.

div

_

u

i64

.

div

_

u

|

i64

.

rem

_

s

i64

.

rem

_

s

|

i64

.

rem

_

u

i64

.

rem

_

u

|

i64

.

and

i64

.

and

|

i64

.

or

i64

.

or

|

i64

.

xor

i64

.

xor

|

i64

.

shl

i64

.

shl

|

i64

.

shr

_

s

i64

.

shr

_

s

|

i64

.

shr

_

u

i64

.

shr

_

u

|

i64

.

rotl

i64

.

rotl

|

i64

.

rotr

i64

.

rotr

166

Chapter 6. Text Format

 

 

 

 

 

 

 

Content      ..     10      11      12      13     ..