webassemblyjs
webassemblyjs copied to clipboard
Capture lost information of number values in JS floats
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
NaNrepresentations 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 aNaNcould be reinterpreted as ani64integer for example. The same applies to the sign bit I think. -
+-0: It is possible to distinguish
+0and-0in 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.
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/
#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.
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.