wasmi-labs / wasmi

WebAssembly (Wasm) interpreter.
https://wasmi-labs.github.io/wasmi/
Apache License 2.0
1.62k stars 291 forks source link

Wasmi returns unexpected NaN bit pattern #569

Open erxiaozhou opened 2 years ago

erxiaozhou commented 2 years ago

Description

Current State

0x0 0x0 0x0 0x2f 0x0 0x0 0xf0 0xff

Expected

........ 0xf8 0xff (The most significant bit of payload is 1)

Environment

Steps to Reproduce

wasmi.zip

  1. build the wasmi
  2. run the test case by wasmi <test_case_name> to_test
Robbepop commented 2 years ago

wasmtime run wasmi_nan.wasm --invoke to_test prints NaN and wasmi_cli wasmi_nan.wasm to_test prints NaN as well. What else do you expect exactly? There is no differentiation between +NaN and -NaN in case you mean that.

erxiaozhou commented 2 years ago

wasmtime run wasmi_nan.wasm --invoke to_test prints NaN and wasmi_cli wasmi_nan.wasm to_test prints NaN as well. What else do you expect exactly? There is no differentiation between +NaN and -NaN in case you mean that.

Thank you for your reply. The output is NaN is as expeced. However, according to the specification https://webassembly.github.io/spec/core/exec/numerics.html#floating-point-operations, in this example, for the value on the stack, the most significant bit of payload is supposed to be 1. It means the highest 13 bits are 0111 1111 1111 1 or 1111 1111 1111 1 . In this example. The highest 13 bit of the value on the stack is 1111 1111 1111 1.

image

Thank you!

Robbepop commented 1 year ago

With respect to Wasm spec testsuite compliance for NaN values in wasmi I found that wasmi's current spec testsuite is not 100% correct on the semantics of NaN value checking compared to what Wasmtime does here: https://github.com/bytecodealliance/wasmtime/blob/main/crates/wast/src/core.rs#L106

In contrast, wasmi simply evaluates .is_nan(). I am sure we can find and fix those NaN sign bit errors by improving the Wasm spec testsuite in this regard.

Robbepop commented 1 month ago

@erxiaozhou I just re-ran the above test with Wasmi v0.38.0 and got the following result:

Original output of old Wasmi version from bug report: 00 00 00 2F 00 00 F0 FF Expected output: 00 00 00 2F 00 00 F8 FF

% wasmi_cli 04-original.wasm
nan:0x7FF8000000000039

I guess the bits have to be swapped: 39 00 00 00 00 00 F8 7F So while the end now seems to be correct we have the 39 byte at the start and are still missing the 2F byte in the middle ...

Wasmtime funnily just returns a NaN without further description:

% wasmtime 04-original.wasm
NaN