webassemblyjs icon indicating copy to clipboard operation
webassemblyjs copied to clipboard

Capture lost information of number values in JS floats

Open maurobringolf opened this issue 7 years ago • 3 comments

Since we are interpreting in JS it makes sense to use JS floats for all numbers and their operations wherever possible. However, I think there are a few problems with that:

  • NaN: There are many different NaN representations containing a payload. I don't think that there is a way to access the payload in JS (or that it is propagated through operations at all). But the WebAssembly spec says that the payloads should propagate through operations according to well-defined rules https://webassembly.github.io/spec/core/exec/numerics.html#aux-nans. I think this is important, because the bits of a NaN could be reinterpreted as an i64 integer for example. The same applies to the sign bit I think.

  • +-0: It is possible to distinguish +0 and -0 in JS but not with ===. That is why test cases with these values are currently useless, because the testing framework in JS treats them as the same. Again, I think we need to store some extra information about the sign.

I will try to come up with some simple examples and run them through the reference interpreter to make the issue more clear. We dont have enough implemented yet to show the NaN issues, but here is a sample test case with the +-0 issue https://github.com/xtuc/js-webassembly-interpreter/blob/master/test/interpreter/kernel/exec/numeric-instructions.js#L383-L398.

maurobringolf avatar Dec 28 '17 18:12 maurobringolf

It's clear enough to me.

I would box every numbers in JS and add this informations.

Btw I recommend you testing with https://mbebenita.github.io/WasmExplorer/

xtuc avatar Dec 28 '17 19:12 xtuc

#49 Fixes the test issue with +-0. I think its enough to store the extra information for NaNs. My idea would be to make a maybeNumber type that looks something like this (pseudocode):

{
  isNaN: false|true,
  value: number
}

The payload of a NaN is a positive integer, so we can store the sign with it. If the value is negative, then its absolute value is the payload and the NaN has a negative sign.

We'd have to change all existing floating point operations though, such that they work with this kind of inputs instead of numbers.

What do you think @xtuc ? I'm happy to do it, but maybe there is a simpler way.

maurobringolf avatar Dec 31 '17 09:12 maurobringolf

Lgtm. We need to make sure to not use Number.isNaN anymore.

I think that we can store the sign too. We could use it for faster comparaison or for the i64 (2x i32) type.

xtuc avatar Dec 31 '17 10:12 xtuc