How the value of type "i32" is evaluated in WebAssembly?

1

As per the text from spec as below:

Note that the value types i32 and i64 are not inherently signed or unsigned. The interpretation of these types is determined by individual operators.

Since we do not know the signedness of the passing parameter of type i32, so how does the i32.add could perform the addition operation on these two parameters? And if we export this function to JavaScript, how the result should be evaluated? for example, 0xffffffff could be evaluated into different number with different signedness (4294967295 or -1).

(module
  (func (export "addTwo") (param i32 i32) (result i32)
    local.get 0
    local.get 1
    i32.add))
webassembly
asked on Stack Overflow Aug 13, 2020 by YHSPY

2 Answers

1

The sign does not matter for addition. If you have some bits X, then they can be interpreted as either a signed value S_X or unsigned value U_X. The important thing is that the difference between the two is either 0 or 2^32, because of how two's complement works.

For example if X is all 1's, then S_X == -1 and U_X == 2^32 - 1. Note the difference is 2^32. And if X is all 0's then both values are 0, and the difference is 0.

So you can write S_X = U_X + D_X where D_X is the difference, and is either 0 or 2^32. Signed addition of X to Y is then

S_X + S_Y = U_X + D_X + U_Y + D_Y = U_X + U_Y

The last step is the important one: we can just ignore the D_* values because they are a multiple of 2^32, and we assume that we wrap around - that is, the bits higher than 32 are just ignored.

That's not true for all operations. For example division has two operations, signed and unsigned, for this reason. But addition, subtraction, multiplication, etc., do not care about the sign.

answered on Stack Overflow Aug 17, 2020 by Alon Zakai
0

WebAssembly requires writing -a + b as b - a.

Using WebAssembly Explorer, this:

int add(int a, int b) { return a + b; }

Compiles to this:

(i32.add(get_local $1)(get_local $0))

While this (note the negative -a):

int add(int a, int b) { return -a + b; }

Compiles to this (note subtract instead of add):

(i32.sub(get_local $0)(get_local $1))
answered on Stack Overflow Aug 13, 2020 by GirkovArpa • edited Aug 13, 2020 by GirkovArpa

User contributions licensed under CC BY-SA 3.0