WebAssembly execution is defined in terms of a stack machine. Some types of instructions pushe a number to a stack. Some instructions pops one number or numbers from the stack, execute and push the result to the stack or not.

For example, if you want to do addition, use`i32.const`

to pushe a 32-bit integer onto the stack twice. `i32.add`

pops two `i32`

numbers , computes their sum and pushes the resulting `i32`

number.

Of course, all processed data are bytes. What you push to the stack are bytes. What you pop from the stack are bytes. What the point of view you take for these bytes is the concept of data types. Once you have a data type, you can use concrete concepts to deal with data, not drop into 0 and 1 directly.

WebAssembly currently has four available types:

`i32`

: 32-bit integer`i64`

: 64-bit integer`f32`

: 32-bit float`f64`

: 64-bit float

You might ask: are `i32`

and `i64`

signed or unsigned integers? The number type `i32`

and `i64`

are not inherently signed or unsigned. What you push or pop are bytes. The interpretation of these types is determined by individual operators.

For example, you can use `i32.const`

to push a 32-bit number onto to the stack.

```
(module
(func $main
i32.const 2147483647
drop
)
(start $main)
)
```

The binary representation of 2147483647 is `1111111 11111111 11111111 11111111`

. `i32.const`

view these bytes as a 32-bit integers and use the little-endian order to push `01111111 11111111 11111111 11111111`

to the stack.

The `drop`

operator can be used to explicitly pop a number from the stack and drop the number directly. You use it here because a function is one type of block (explained in later documents). The `$main`

function returns nothing so you have to empty the stack before leaving the function. If not, an error happens.

How about the number 2147483648?

```
(module
(func $main
i32.const 2147483648
drop
)
(start $main)
)
```

The binary representation of 2147483648 is `10000000 00000000 00000000 00000000`

. `i32.const`

view these bytes as a 32-bit integers and use the little-endian order to push `10000000 00000000 00000000 00000000`

to the stack. So, the above code has the same result as the following.

```
(module
(func $main
i32.const -2147483648
drop
)
(start $main)
)
```

WebAssembly uses 2's complement as a method of signed number representation so the binary representation of -2147483648 is also `10000000 00000000 00000000 00000000`

.

If you change `i32`

to `i64`

:

```
(module
(func $main
i64.const 2147483648
drop
)
(start $main)
)
```

The binary representation of 2147483648 is `10000000 00000000 00000000 00000000`

. `i64.const`

view these bytes as a 64-bit integers and use the little-endian order to push `00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000`

to the stack.

When communicating with JavaScript, one thing you should note is, JavaScript stores numbers in double-precision 64-bit binary format IEEE 754. When representing integers, the maximum safe integer is 2^{53} - 1 and the minimum safe integer is -(2^{53} - 1). You cannot declare `i64`

when communicating with JavaScript. For example, the following code will has an error.

```
(module
(import "env" "log" (func $log (param i64)))
(func $main
i64.const 2147483648
call $log
)
(start $main)
)
```

Changing `i64`

to `f64`

solves the problem.

```
(module
(import "env" "log" (func $log (param f64)))
(func $main
f64.const 2147483648
call $log
)
(start $main)
)
```

Numbers can be written as decimals and hexidecimal. To input in hexdecimal notation, prefix with `0x`

. The floating point types can also be expressed using `E`

or `e`

for scientific notation. `inf`

means infinity. `nan`

means NaN (Not a number).