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

 

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

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     1      2      3      4      ..

 

 

 

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

 

 

2.2 Values

WebAssembly programs operate on primitive numeric

values

. Moreover, in the definition of programs, immutable

sequences of values occur to represent more complex data, such as text strings or other vectors.

2.2.1 Bytes

The simplest form of value are raw uninterpreted

bytes

. In the abstract syntax they are represented as hexadecimal

literals.

byte

::=

0x00

|

. . .

|

0xFF

Conventions

• The meta variable

𝑏

ranges over bytes.

• Bytes are sometimes interpreted as natural numbers

𝑛 <

256

.

2.2.2 Integers

Different classes of

integers

with different value ranges are distinguished by their

bit width

𝑁

and by whether they

are

unsigned

or

signed

.

u

𝑁

::=

0

|

1

|

. . .

|

2

𝑁

1

s

𝑁

::=

2

𝑁

1

|

. . .

| −

1

|

0

|

1

|

. . .

|

2

𝑁

1

1

i

𝑁

::=

u

𝑁

The latter class defines

uninterpreted

integers, whose signedness interpretation can vary depending on context. In

the abstract syntax, they are represented as unsigned values. However, some operations

convert

them to signed

based on a two’s complement interpretation.

Note:

The main integer types occurring in this specification are

u32

,

u64

,

s32

,

s64

,

i8

,

i16

,

i32

,

i64

However,

other sizes occur as auxiliary constructions, e.g., in the definition of

floating-point

numbers.

Conventions

• The meta variables

𝑚, 𝑛, 𝑖

range over integers.

• Numbers may be denoted by simple arithmetics, as in the grammar above. In order to distinguish arithmetics

like

2

𝑁

from sequences like

(1)

𝑁

, the latter is distinguished with parentheses.

2.2.3 Floating-Point

Floating-point

data represents 32 or 64 bit values that correspond to the respective binary formats of the

IEEE

754-2019

9

standard (Section 3.3).

Every value has a

sign

and a

magnitude

. Magnitudes can either be expressed as

normal

numbers of the form

𝑚

0

.𝑚

1

𝑚

2

. . . 𝑚

𝑀

·

2

𝑒

, where

𝑒

is the exponent and

𝑚

is the

significand

whose most significant bit

𝑚

0

is

1

, or as a

subnormal

number where the exponent is fixed to the smallest possible value and

𝑚

0

is

0

; among the subnormals

are positive and negative zero values. Since the significands are binary values, normals are represented in the form

(1 +

𝑚

·

2

𝑀

)

·

2

𝑒

, where

𝑀

is the bit width of

𝑚

; similarly for subnormals.

9

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

2.2. Values

7

Possible magnitudes also include the special values

(infinity) and

nan

(

NaN

, not a number). NaN values have a

payload

that describes the mantissa bits in the underlying

binary representation

No distinction is made between

signalling and quiet NaNs.

f

𝑁

::=

+

f Nmag

f Nmag

f Nmag

::=

(1 +

u

𝑀

·

2

𝑀

)

·

2

𝑒

(

if

2

𝐸

1

+ 2

𝑒

2

𝐸

1

1)

|

(0 +

u

𝑀

·

2

𝑀

)

·

2

𝑒

(

if

𝑒

=

2

𝐸

1

+ 2)

|

|

nan

(

𝑛

)

(

if

1

𝑛 <

2

𝑀

)

where

𝑀

=

signif

(

𝑁

)

and

𝐸

=

expon

(

𝑁

)

with

signif

(32)

=

23

expon

(32)

=

8

signif

(64)

=

52

expon

(64)

=

11

A

canonical NaN

is a floating-point value

±

nan

(

canon

𝑁

)

where

canon

𝑁

is a payload whose most significant bit

is

1

while all others are

0

:

canon

𝑁

2

signif

(

𝑁

)

1

An

arithmetic NaN

is a floating-point value

±

nan

(

𝑛

)

with

𝑛

canon

𝑁

, such that the most significant bit is

1

while all others are arbitrary.

Note:

In the abstract syntax, subnormals are distinguished by the leading 0 of the significand. The exponent

of subnormals has the same value as the smallest possible exponent of a normal number. Only in the

binary

representation

the exponent of a subnormal is encoded differently than the exponent of any normal number.

Conventions

• The meta variable

𝑧

ranges over floating-point values where clear from context.

2.2.4 Vectors

Numeric vectors

are 128-bit values that are processed by vector instructions (also known as

SIMD

instructions,

single instruction multiple data). They are represented in the abstract syntax using

i128

The interpretation of

lane types (

integer

or

floating-point

numbers) and lane sizes are determined by the specific instruction operating

on them.

2.2.5 Names

Names

are sequences of

characters

, which are

scalar values

as defined by

Unicode

10

(Section 2.4).

name

::=

char

*

(

if

|

utf8

(

char

*

)

|

<

2

32

)

char

::=

U+00

|

. . .

|

U+D7FF

|

U+E000

|

. . .

|

U+10FFFF

Due to the limitations of the

binary format

the length of a name is bounded by the length of its

UTF-8

encoding.

10

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

8

Chapter 2. Structure

Convention

• Characters (Unicode scalar values) are sometimes used interchangeably with natural numbers

𝑛 <

1114112

.

2.3 Types

Various entities in WebAssembly are classified by types. Types are checked during

validation

,

instantiation

and

possibly

execution

.

2.3.1 Number Types

Number types

classify numeric values.

numtype

::=

i32

|

i64

|

f32

|

f64

The types

i32

and

i64

classify 32 and 64 bit integers, respectively. Integers are not inherently signed or unsigned,

their interpretation is determined by individual operations.
The types

f32

and

f64

classify 32 and 64 bit floating-point data, respectively. They correspond to the respective

binary floating-point representations, also known as

single

and

double

precision, as defined by the

IEEE 754-2019

11

standard (Section 3.3).
Number types are

transparent

, meaning that their bit patterns can be observed. Values of number type can be stored

in

memories

.

Conventions

• The notation

|

𝑡

|

denotes the

bit width

of a number type

𝑡

. That is,

|

i32

|

=

|

f32

|

= 32

and

|

i64

|

=

|

f64

|

= 64

.

2.3.2 Vector Types

Vector types

classify vectors of

numeric

values processed by vector instructions (also known as

SIMD

instructions,

single instruction multiple data).

vectype

::=

v128

The type

v128

corresponds to a 128 bit vector of packed integer or floating-point data. The packed data can be

interpreted as signed or unsigned integers, single or double precision floating-point values, or a single 128 bit type.

The interpretation is determined by individual operations.
Vector types, like

number types

are

transparent

, meaning that their bit patterns can be observed. Values of vector

type can be stored in

memories

.

Conventions

• The notation

|

𝑡

|

for

bit width

extends to vector types as well, that is,

|

v128

|

= 128

.

11

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

2.3. Types

9

2.3.3 Reference Types

Reference types

classify first-class references to objects in the runtime

store

.

reftype

::=

funcref

|

externref

The type

funcref

denotes the infinite union of all references to

functions

regardless of their

function types

.

The type

externref

denotes the infinite union of all references to objects owned by the

embedder

and that can be

passed into WebAssembly under this type.
Reference types are

opaque

, meaning that neither their size nor their bit pattern can be observed. Values of reference

type can be stored in

tables

.

2.3.4 Value Types

Value types

classify the individual values that WebAssembly code can compute with and the values that a variable

accepts. They are either

number types

,

vector types

or

reference types

.

valtype

::=

numtype

|

vectype

|

reftype

Conventions

• The meta variable

𝑡

ranges over value types or subclasses thereof where clear from context.

2.3.5 Result Types

Result types

classify the result of

executing instructions

or

functions

which is a sequence of values, written with

brackets.

resulttype

::=

[

vec

(

valtype

)]

2.3.6 Function Types

Function types

classify the signature of

functions

mapping a vector of parameters to a vector of results. They are

also used to classify the inputs and outputs of

instructions

.

functype

::=

resulttype

resulttype

2.3.7 Limits

Limits

classify the size range of resizeable storage associated with

memory types

and

table types

.

limits

::=

{

min

u32

,

max

u32

?

}

If no maximum is given, the respective storage can grow to any size.

10

Chapter 2. Structure

2.3.8 Memory Types

Memory types

classify linear

memories

and their size range.

memtype

::=

limits

The limits constrain the minimum and optionally the maximum size of a memory. The limits are given in units of

page size

.

2.3.9 Table Types

Table types

classify

tables

over elements of

reference type

within a size range.

tabletype

::=

limits reftype

Like memories, tables are constrained by limits for their minimum and optionally maximum size. The limits are

given in numbers of entries.

Note:

In future versions of WebAssembly, additional element types may be introduced.

2.3.10 Global Types

Global types

classify

global

variables, which hold a value and can either be mutable or immutable.

globaltype

::=

mut valtype

mut

::=

const

|

var

2.3.11 External Types

External types

classify

imports

and

external values

with their respective types.

externtype

::=

func

functype

|

table

tabletype

|

mem

memtype

|

global

globaltype

Conventions

The following auxiliary notation is defined for sequences of external types. It filters out entries of a specific kind

in an order-preserving fashion:

funcs

(

externtype

*

) = [

functype

|

(

func

functype

)

externtype

*

]

tables

(

externtype

*

) = [

tabletype

|

(

table

tabletype

)

externtype

*

]

mems

(

externtype

*

) = [

memtype

|

(

mem

memtype

)

externtype

*

]

globals

(

externtype

*

) = [

globaltype

|

(

global

globaltype

)

externtype

*

]

2.3. Types

11

2.4 Instructions

WebAssembly code consists of sequences of

instructions

. Its computational model is based on a

stack machine

in that instructions manipulate values on an implicit

operand stack

, consuming (popping) argument values and

producing or returning (pushing) result values.
In addition to dynamic operands from the stack, some instructions also have static

immediate

arguments, typically

indices

or type annotations, which are part of the instruction itself.

Some instructions are

structured

in that they bracket nested sequences of instructions.

The following sections group instructions into a number of different categories.

2.4.1 Numeric Instructions

Numeric instructions provide basic operations over numeric

values

of specific

type

These operations closely match

respective operations available in hardware.

nn

,

mm

::=

32

|

64

sx

::=

u

|

s

instr

::=

i

nn

.

const

i nn

|

f

nn

.

const

f nn

|

i

nn

.

iunop

|

f

nn

.

funop

|

i

nn

.

ibinop

|

f

nn

.

fbinop

|

i

nn

.

itestop

|

i

nn

.

irelop

|

f

nn

.

frelop

|

i

nn

.

extend

8

_

s

|

i

nn

.

extend

16

_

s

|

i64

.

extend

32

_

s

|

i32

.

wrap

_

i64

|

i64

.

extend

_

i32

_

sx

|

i

nn

.

trunc

_

f

mm

_

sx

|

i

nn

.

trunc

_

sat

_

f

mm

_

sx

|

f32

.

demote

_

f64

|

f64

.

promote

_

f32

|

f

nn

.

convert

_

i

mm

_

sx

|

i

nn

.

reinterpret

_

f

nn

|

f

nn

.

reinterpret

_

i

nn

|

. . .

iunop

::=

clz

|

ctz

|

popcnt

ibinop

::=

add

|

sub

|

mul

|

div

_

sx

|

rem

_

sx

|

and

|

or

|

xor

|

shl

|

shr

_

sx

|

rotl

|

rotr

funop

::=

abs

|

neg

|

sqrt

|

ceil

|

floor

|

trunc

|

nearest

fbinop

::=

add

|

sub

|

mul

|

div

|

min

|

max

|

copysign

itestop

::=

eqz

irelop

::=

eq

|

ne

|

lt

_

sx

|

gt

_

sx

|

le

_

sx

|

ge

_

sx

frelop

::=

eq

|

ne

|

lt

|

gt

|

le

|

ge

Numeric instructions are divided by

number type

For each type, several subcategories can be distinguished:

Constants

: return a static constant.

Unary Operations

: consume one operand and produce one result of the respective type.

Binary Operations

: consume two operands and produce one result of the respective type.

Tests

: consume one operand of the respective type and produce a Boolean integer result.

Comparisons

: consume two operands of the respective type and produce a Boolean integer result.

Conversions

: consume a value of one type and produce a result of another (the source type of the conversion

is the one after the “_”).

Some integer instructions come in two flavors, where a signedness annotation

sx

distinguishes whether the operands

are to be

interpreted

as

unsigned

or

signed

integers. For the other integer instructions, the use of two’s complement

for the signed interpretation means that they behave the same regardless of signedness.

12

Chapter 2. Structure

Conventions

Occasionally, it is convenient to group operators together according to the following grammar shorthands:

unop

::=

iunop

|

funop

|

extend

𝑁

_

s

binop

::=

ibinop

|

fbinop

testop

::=

itestop

relop

::=

irelop

|

frelop

cvtop

::=

wrap

|

extend

|

trunc

|

trunc

_

sat

|

convert

|

demote

|

promote

|

reinterpret

2.4. Instructions

13

14

Chapter 2. Structure

2.4.2 Vector Instructions

Vector instructions (also known as

SIMD

instructions, single data multiple value) provide basic operations over

values

of

vector type

.

ishape

::=

i8x16

|

i16x8

|

i32x4

|

i64x2

fshape

::=

f32x4

|

f64x2

shape

::=

ishape

|

fshape

half

::=

low

|

high

laneidx

::=

u8

instr

::=

. . .

|

v128

.

const

i128

|

v128

.

vvunop

|

v128

.

vvbinop

|

v128

.

vvternop

|

v128

.

vvtestop

|

i8x16

.

shuffle

laneidx

16

|

i8x16

.

swizzle

|

shape

.

splat

|

i8x16

.

extract

_

lane

_

sx laneidx

|

i16x8

.

extract

_

lane

_

sx laneidx

|

i32x4

.

extract

_

lane

laneidx

|

i64x2

.

extract

_

lane

laneidx

|

fshape

.

extract

_

lane

laneidx

|

shape

.

replace

_

lane

laneidx

|

i8x16

.

virelop

|

i16x8

.

virelop

|

i32x4

.

virelop

|

i64x2

.

eq

|

i64x2

.

ne

|

i64x2

.

lt

_

s

|

i64x2

.

gt

_

s

|

i64x2

.

le

_

s

|

i64x2

.

ge

_

s

|

fshape

.

vfrelop

|

ishape

.

viunop

|

i8x16

.

popcnt

|

i16x8

.

q15mulr

_

sat

_

s

|

i32x4

.

dot

_

i16x8

_

s

|

fshape

.

vfunop

|

ishape

.

vitestop

|

ishape

.

bitmask

|

i8x16

.

narrow

_

i16x8

_

sx

|

i16x8

.

narrow

_

i32x4

_

sx

|

i16x8

.

extend

_

half

_

i8x16

_

sx

|

i32x4

.

extend

_

half

_

i16x8

_

sx

|

i64x2

.

extend

_

half

_

i32x4

_

sx

|

ishape

.

vishiftop

|

ishape

.

vibinop

|

i8x16

.

viminmaxop

|

i16x8

.

viminmaxop

|

i32x4

.

viminmaxop

|

i8x16

.

visatbinop

|

i16x8

.

visatbinop

|

i16x8

.

mul

|

i32x4

.

mul

|

i64x2

.

mul

|

i8x16

.

avgr

_

u

|

i16x8

.

avgr

_

u

|

i16x8

.

extmul

_

half

_

i8x16

_

sx

|

i32x4

.

extmul

_

half

_

i16x8

_

sx

|

i64x2

.

extmul

_

half

_

i32x4

_

sx

|

i16x8

.

extadd

_

pairwise

_

i8x16

_

sx

|

i32x4

.

extadd

_

pairwise

_

i16x8

_

sx

|

fshape

.

vfbinop

|

i32x4

.

trunc

_

sat

_

f32x4

_

sx

|

i32x4

.

trunc

_

sat

_

f64x2

_

sx

_

zero

|

f32x4

.

convert

_

i32x4

_

sx

|

f32x4

.

demote

_

f64x2

_

zero

|

f64x2

.

convert

_

low

_

i32x4

_

sx

|

f64x2

.

promote

_

low

_

f32x4

|

. . .

vvunop

::=

not

vvbinop

::=

and

|

andnot

|

or

|

xor

vvternop

::=

bitselect

vvtestop

::=

any

_

true

vitestop

::=

all

_

true

virelop

::=

eq

|

ne

|

lt

_

sx

|

gt

_

sx

|

le

_

sx

|

ge

_

sx

vfrelop

::=

eq

|

ne

|

lt

|

gt

|

le

|

ge

viunop

::=

abs

|

neg

vibinop

::=

add

|

sub

viminmaxop

::=

min

_

sx

|

max

_

sx

visatbinop

::=

add

_

sat

_

sx

|

sub

_

sat

_

sx

vishiftop

::=

shl

|

shr

_

sx

vfunop

::=

abs

|

neg

|

sqrt

|

ceil

|

floor

|

trunc

|

nearest

vfbinop

::=

add

|

sub

|

mul

|

div

|

min

|

max

|

pmin

|

pmax

2.4. Instructions

15

Vector instructions have a naming convention involving a prefix that determines how their operands will be inter-

preted. This prefix describes the

shape

of the operand, written

𝑡

x

𝑁

, and consisting of a packed

numeric type

𝑡

and

the number of

lanes

𝑁

of that type. Operations are performed point-wise on the values of each lane.

Note:

For example, the shape

i32x4

interprets the operand as four

i32

values, packed into an

i128

The bitwidth

of the numeric type

𝑡

times

𝑁

always is 128.

Instructions prefixed with

v128

do not involve a specific interpretation, and treat the

v128

as an

i128

value or a

vector of 128 individual bits.
Vector instructions can be grouped into several subcategories:

Constants

: return a static constant.

Unary Operations

: consume one

v128

operand and produce one

v128

result.

Binary Operations

: consume two

v128

operands and produce one

v128

result.

Ternary Operations

: consume three

v128

operands and produce one

v128

result.

Tests

: consume one

v128

operand and produce a Boolean integer result.

Shifts

: consume a

v128

operand and a

i32

operand, producing one

v128

result.

Splats

: consume a value of numeric type and produce a

v128

result of a specified shape.

Extract lanes

: consume a

v128

operand and return the numeric value in a given lane.

Replace lanes

: consume a

v128

operand and a numeric value for a given lane, and produce a

v128

result.

Some vector instructions have a signedness annotation

sx

which distinguishes whether the elements in the operands

are to be

interpreted

as

unsigned

or

signed

integers. For the other vector instructions, the use of two’s complement

for the signed interpretation means that they behave the same regardless of signedness.

Conventions

Occasionally, it is convenient to group operators together according to the following grammar shorthands:

vunop

::=

viunop

|

vfunop

|

popcnt

vbinop

::=

vibinop

|

vfbinop

|

viminmaxop

|

visatbinop

|

mul

|

avgr

_

u

|

q15mulr

_

sat

_

s

vtestop

::=

vitestop

vrelop

::=

virelop

|

vfrelop

vcvtop

::=

extend

|

trunc

_

sat

|

convert

|

demote

|

promote

2.4.3 Reference Instructions

Instructions in this group are concerned with accessing

references

.

instr

::=

. . .

|

ref

.

null

reftype

|

ref

.

is

_

null

|

ref

.

func

funcidx

These instruction produce a null value, check for a null value, or produce a reference to a given function, respec-

tively.

16

Chapter 2. Structure

2.4.4 Parametric Instructions

Instructions in this group can operate on operands of any

value type

.

instr

::=

. . .

|

drop

|

select

(

valtype

*

)

?

The

drop

instruction simply throws away a single operand.

The

select

instruction selects one of its first two operands based on whether its third operand is zero or not. It may

include a

value type

determining the type of these operands. If missing, the operands must be of

numeric type

.

Note:

In future versions of WebAssembly, the type annotation on

select

may allow for more than a single value

being selected at the same time.

2.4.5 Variable Instructions

Variable instructions are concerned with access to

local

or

global

variables.

instr

::=

. . .

|

local

.

get

localidx

|

local

.

set

localidx

|

local

.

tee

localidx

|

global

.

get

globalidx

|

global

.

set

globalidx

These instructions get or set the values of variables, respectively. The

local

.

tee

instruction is like

local

.

set

but also

returns its argument.

2.4.6 Table Instructions

Instructions in this group are concerned with tables

table

.

instr

::=

. . .

|

table

.

get

tableidx

|

table

.

set

tableidx

|

table

.

size

tableidx

|

table

.

grow

tableidx

|

table

.

fill

tableidx

|

table

.

copy

tableidx tableidx

|

table

.

init

tableidx elemidx

|

elem

.

drop

elemidx

The

table

.

get

and

table

.

set

instructions load or store an element in a table, respectively.

The

table

.

size

instruction returns the current size of a table. The

table

.

grow

instruction grows table by a given

delta and returns the previous size, or

1

if enough space cannot be allocated. It also takes an initialization value

for the newly allocated entries.
The

table

.

fill

instruction sets all entries in a range to a given value.

The

table

.

copy

instruction copies elements from a source table region to a possibly overlapping destination region;

the first index denotes the destination. The

table

.

init

instruction copies elements from a

passive element segment

into a table. The

elem

.

drop

instruction prevents further use of a passive element segment. This instruction is

intended to be used as an optimization hint. After an element segment is dropped its elements can no longer be

retrieved, so the memory used by this segment may be freed.
An additional instruction that accesses a table is the

control instruction

call

_

indirect

.

2.4. Instructions

17

2.4.7 Memory Instructions

Instructions in this group are concerned with linear

memory

.

memarg

::=

{

offset

u32

,

align

u32

}

ww

::=

8

|

16

|

32

|

64

instr

::=

. . .

|

i

nn

.

load

memarg

|

f

nn

.

load

memarg

|

v128

.

load

memarg

|

i

nn

.

store

memarg

|

f

nn

.

store

memarg

|

v128

.

store

memarg

|

i

nn

.

load

8

_

sx memarg

|

i

nn

.

load

16

_

sx memarg

|

i64

.

load

32

_

sx memarg

|

i

nn

.

store

8

memarg

|

i

nn

.

store

16

memarg

|

i64

.

store

32

memarg

|

v128

.

load

8x8

_

sx memarg

|

v128

.

load

16x4

_

sx memarg

|

v128

.

load

32x2

_

sx memarg

|

v128

.

load

32

_

zero

memarg

|

v128

.

load

64

_

zero

memarg

|

v128

.

load

ww

_

splat

memarg

|

v128

.

load

ww

_

lane

memarg laneidx

|

v128

.

store

ww

_

lane

memarg laneidx

|

memory

.

size

|

memory

.

grow

|

memory

.

fill

|

memory

.

copy

|

memory

.

init

dataidx

|

data

.

drop

dataidx

Memory is accessed with

load

and

store

instructions for the different

number types

They all take a

memory

immediate

memarg

that contains an address

offset

and the expected

alignment

(expressed as the exponent of a

power of 2). Integer loads and stores can optionally specify a

storage size

that is smaller than the

bit width

of the

respective value type. In the case of loads, a sign extension mode

sx

is then required to select appropriate behavior.

Vector loads can specify a shape that is half the

bit width

of

v128

Each lane is half its usual size, and the sign

extension mode

sx

then specifies how the smaller lane is extended to the larger lane. Alternatively, vector loads

can perform a

splat

, such that only a single lane of the specified storage size is loaded, and the result is duplicated

to all lanes.
The static address offset is added to the dynamic address operand, yielding a 33 bit

effective address

that is the

zero-based index at which the memory is accessed. All values are read and written in

little endian

12

byte order. A

trap

results if any of the accessed memory bytes lies outside the address range implied by the memory’s current

size.

Note:

Future version of WebAssembly might provide memory instructions with 64 bit address ranges.

The

memory

.

size

instruction returns the current size of a memory. The

memory

.

grow

instruction grows memory

by a given delta and returns the previous size, or

1

if enough memory cannot be allocated. Both instructions

operate in units of

page size

.

The

memory

.

fill

instruction sets all values in a region to a given byte. The

memory

.

copy

instruction copies data

from a source memory region to a possibly overlapping destination region. The

memory

.

init

instruction copies

data from a

passive data segment

into a memory. The

data

.

drop

instruction prevents further use of a passive data

segment. This instruction is intended to be used as an optimization hint. After a data segment is dropped its data

can no longer be retrieved, so the memory used by this segment may be freed.

Note:

In the current version of WebAssembly, all memory instructions implicitly operate on

memory index

0

.

This restriction may be lifted in future versions.

12

https://en.wikipedia.org/wiki/Endianness#Little-endian

18

Chapter 2. Structure

2.4.8 Control Instructions

Instructions in this group affect the flow of control.

blocktype

::=

typeidx

|

valtype

?

instr

::=

. . .

|

nop

|

unreachable

|

block

blocktype instr

*

end

|

loop

blocktype instr

*

end

|

if

blocktype instr

*

else

instr

*

end

|

br

labelidx

|

br

_

if

labelidx

|

br

_

table

vec

(

labelidx

)

labelidx

|

return

|

call

funcidx

|

call

_

indirect

tableidx typeidx

The

nop

instruction does nothing.

The

unreachable

instruction causes an unconditional

trap

.

The

block

,

loop

and

if

instructions are

structured

instructions. They bracket nested sequences of instructions,

called

blocks

, terminated with, or separated by,

end

or

else

pseudo-instructions. As the grammar prescribes, they

must be well-nested.
A structured instruction can consume

input

and produce

output

on the operand stack according to its annotated

block type

. It is given either as a

type index

that refers to a suitable

function type

or as an optional

value type

inline,

which is a shorthand for the function type

[]

[

valtype

?

]

.

Each structured control instruction introduces an implicit

label

. Labels are targets for branch instructions that

reference them with

label indices

Unlike with other

index spaces

indexing of labels is relative by nesting depth,

that is, label

0

refers to the innermost structured control instruction enclosing the referring branch instruction, while

increasing indices refer to those farther out. Consequently, labels can only be referenced from

within

the associated

structured control instruction. This also implies that branches can only be directed outwards, “breaking” from the

block of the control construct they target. The exact effect depends on that control construct. In case of

block

or

if

it is a

forward jump

, resuming execution after the matching

end

In case of

loop

it is a

backward jump

to the

beginning of the loop.

Note:

This enforces

structured control flow

. Intuitively, a branch targeting a

block

or

if

behaves like a

break

statement in most C-like languages, while a branch targeting a

loop

behaves like a

continue

statement.

Branch instructions come in several flavors:

br

performs an unconditional branch,

br

_

if

performs a conditional

branch, and

br

_

table

performs an indirect branch through an operand indexing into the label vector that is an

immediate to the instruction, or to a default target if the operand is out of bounds. The

return

instruction is a

shortcut for an unconditional branch to the outermost block, which implicitly is the body of the current function.

Taking a branch

unwinds

the operand stack up to the height where the targeted structured control instruction was

entered. However, branches may additionally consume operands themselves, which they push back on the operand

stack after unwinding. Forward branches require operands according to the output of the targeted block’s type, i.e.,

represent the values produced by the terminated block. Backward branches require operands according to the input

of the targeted block’s type, i.e., represent the values consumed by the restarted block.
The

call

instruction invokes another

function

consuming the necessary arguments from the stack and returning the

result values of the call. The

call

_

indirect

instruction calls a function indirectly through an operand indexing into a

table

that is denoted by a

table index

and must have type

funcref

Since it may contain functions of heterogeneous

type, the callee is dynamically checked against the

function type

indexed by the instruction’s second immediate,

and the call is aborted with a

trap

if it does not match.

2.4. Instructions

19

2.4.9 Expressions

Function

bodies, initialization values for

globals

and offsets of

element

or

data

segments are given as expressions,

which are sequences of

instructions

terminated by an

end

marker.

expr

::=

instr

*

end

In some places, validation

restricts

expressions to be

constant

, which limits the set of allowable instructions.

2.5 Modules

WebAssembly programs are organized into

modules

, which are the unit of deployment, loading, and compilation.

A module collects definitions for

types

,

functions

,

tables

,

memories

and

globals

In addition, it can declare

imports

and

exports

and provide initialization in the form of

data

and

element

segments, or a

start function

.

module

::=

{

types

vec

(

functype

)

,

funcs

vec

(

func

)

,

tables

vec

(

table

)

,

mems

vec

(

mem

)

,

globals

vec

(

global

)

,

elems

vec

(

elem

)

,

datas

vec

(

data

)

,

start

start

?

,

imports

vec

(

import

)

,

exports

vec

(

export

)

}

Each of the vectors – and thus the entire module – may be empty.

2.5.1 Indices

Definitions are referenced with zero-based

indices

. Each class of definition has its own

index space

, as distinguished

by the following classes.

typeidx

::=

u32

funcidx

::=

u32

tableidx

::=

u32

memidx

::=

u32

globalidx

::=

u32

elemidx

::=

u32

dataidx

::=

u32

localidx

::=

u32

labelidx

::=

u32

The index space for

functions

,

tables

,

memories

and

globals

includes respective

imports

declared in the same

module. The indices of these imports precede the indices of other definitions in the same index space.
Element indices reference

element segments

and data indices reference

data segments

.

The index space for

locals

is only accessible inside a

function

and includes the parameters of that function, which

precede the local variables.
Label indices reference

structured control instructions

inside an instruction sequence.

20

Chapter 2. Structure

Conventions

• The meta variable

𝑙

ranges over label indices.

• The meta variables

𝑥, 𝑦

range over indices in any of the other index spaces.

• The notation

idx(

𝐴

)

denotes the set of indices from index space

idx

occurring free in

𝐴

. We sometimes

reinterpret this set as the

vector

of its elements.

Note:

For example, if

instr

*

is

(

data

.

drop

𝑥

)(

memory

.

init

𝑦

)

, then

dataidx

(

instr

*

) =

{

𝑥, 𝑦

}

, or equivalently,

the vector

𝑥 𝑦

.

2.5.2 Types

The

types

component of a module defines a vector of

function types

.

All function types used in a module must be defined in this component. They are referenced by

type indices

.

Note:

Future versions of WebAssembly may add additional forms of type definitions.

2.5.3 Functions

The

funcs

component of a module defines a vector of

functions

with the following structure:

func

::=

{

type

typeidx

,

locals

vec

(

valtype

)

,

body

expr

}

The

type

of a function declares its signature by reference to a

type

defined in the module. The parameters of the

function are referenced through 0-based

local indices

in the function’s body; they are mutable.

The

locals

declare a vector of mutable local variables and their types. These variables are referenced through

local

indices

in the function’s body. The index of the first local is the smallest index not referencing a parameter.

The

body

is an

instruction

sequence that upon termination must produce a stack matching the function type’s

result

type

.

Functions are referenced through

function indices

starting with the smallest index not referencing a function

im-

port

.

2.5.4 Tables

The

tables

component of a module defines a vector of

tables

described by their

table type

:

table

::=

{

type

tabletype

}

A table is a vector of opaque values of a particular

reference type

The

min

size in the

limits

of the table type

specifies the initial size of that table, while its

max

if present, restricts the size to which it can grow later.

Tables can be initialized through

element segments

.

Tables are referenced through

table indices

starting with the smallest index not referencing a table

import

Most

constructs implicitly reference table index

0

.

2.5. Modules

21

2.5.5 Memories

The

mems

component of a module defines a vector of

linear memories

(or

memories

for short) as described by

their

memory type

:

mem

::=

{

type

memtype

}

A memory is a vector of raw uninterpreted bytes. The

min

size in the

limits

of the memory type specifies the initial

size of that memory, while its

max

if present, restricts the size to which it can grow later. Both are in units of

page

size

.

Memories can be initialized through

data segments

.

Memories are referenced through

memory indices

starting with the smallest index not referencing a memory

im-

port

Most constructs implicitly reference memory index

0

.

Note:

In the current version of WebAssembly, at most one memory may be defined or imported in a single module,

and

all

constructs implicitly reference this memory

0

. This restriction may be lifted in future versions.

2.5.6 Globals

The

globals

component of a module defines a vector of

global variables

(or

globals

for short):

global

::=

{

type

globaltype

,

init

expr

}

Each global stores a single value of the given

global type

Its

type

also specifies whether a global is immutable or

mutable. Moreover, each global is initialized with an

init

value given by a

constant

initializer

expression

.

Globals are referenced through

global indices

starting with the smallest index not referencing a global

import

.

2.5.7 Element Segments

The initial contents of a table is uninitialized.

Element segments

can be used to initialize a subrange of a table from

a static

vector

of elements.

The

elems

component of a module defines a vector of element segments. Each element segment defines a

reference

type

and a corresponding list of

constant

element

expressions

.

Element segments have a mode that identifies them as either

passive

,

active

, or

declarative

. A passive element

segment’s elements can be copied to a table using the

table

.

init

instruction. An active element segment copies its

elements into a table during

instantiation

as specified by a

table index

and a

constant expression

defining an offset

into that table. A declarative element segment is not available at runtime but merely serves to forward-declare

references that are formed in code with instructions like

ref

.

func

.

elem

::=

{

type

reftype

,

init

vec

(

expr

)

,

mode

elemmode

}

elemmode

::=

passive

|

active

{

table

tableidx

,

offset

expr

}

|

declarative

The

offset

is given by a

constant expression

.

Element segments are referenced through

element indices

.

Note:

In the current version of WebAssembly, only tables of element type

funcref

can be initialized with an

element segment. This limitation may be lifted in the future.

22

Chapter 2. Structure

 

 

 

 

 

 

 

 

Content      ..     1      2      3      4      ..