stdweb icon indicating copy to clipboard operation
stdweb copied to clipboard

Overflow in serialization of u64

Open DarthGandalf opened this issue 5 years ago • 1 comments

#[macro_use]
extern crate stdweb;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize)]
struct Foo {
    bar: u64,
}
js_serializable!(Foo);

fn main() {
    println!("Hello, world!");
    let foo = Foo {
        bar: 883498451449996500,
    };
    js! {
        console.log("Hi console", @{foo});
    };
}

results in:

Error loading Rust wasm module 'stdwebbug': RuntimeError: unreachable
    at __rust_start_panic (wasm-function[1089]:0x35849)
    at rust_panic (wasm-function[1084]:0x355e5)
    at _ZN3std9panicking20rust_panic_with_hook17hd6b16d2853327786E (wasm-function[1079]:0x352f4)
    at _ZN3std9panicking18continue_panic_fmt17h70cda879a43284baE (wasm-function[1078]:0x351bf)
    at rust_begin_unwind (wasm-function[1077]:0x35143)
    at _ZN4core9panicking9panic_fmt17hddbe1a30080e00b8E (wasm-function[1108]:0x373cc)
    at _ZN4core6result13unwrap_failed17h5d4087ad0da767ceE (wasm-function[1129]:0x38536)
    at _ZN4core6result19Result$LT$T$C$E$GT$6unwrap17h8deb6e1979685a6fE (wasm-function[71]:0x3aeb)
    at _ZN78_$LT$stdwebbug..Foo$u20$as$u20$stdweb..webcore..serialization..JsSerialize$GT$8_into_js17h50fe674779c4d1b9E (wasm-function[11]:0xbde)
    at _ZN184_$LT$stdweb..webcore..newtype..Newtype$LT$$LP$stdweb..webcore..serialization..NonFunctionTag$C$$u20$$LP$$RP$$RP$$C$T$GT$$u20$as$u20$stdweb..webcore..serialization..JsSerializeOwned$GT$13into_js_owned17h6ffad57c7c97c83cE (wasm-function[86]:0x4e97)

But if I change value of bar to 23, it works as expected.

That is the minimal example; in the full code I'm using I also was able to extract this error message:

panicked at 'called `Result::unwrap()` on an `Err` value: ConversionError { kind: NumberConversionError(OutOfRange) }', src/libcore/result.rs:1165:5
[dependencies]
stdweb = "0.4.20"
serde_derive = "1.0.102"
serde = "1.0.102"

cargo 1.40.0-nightly (a429e8cc4 2019-10-04) cargo-web 0.6.25 rustc 1.40.0-nightly (1721c9685 2019-10-12)

DarthGandalf avatar Nov 28 '19 21:11 DarthGandalf

JavaScript does not have 64-bit integers, it only has 64-bit floating point. So what stdweb does is, it converts the 64-bit integer into a 64-bit floating point and then sends it to JS.

But a 64-bit floating point can only hold 53 bits of data (as an integer), so the biggest number you can send is 9007199254740991 (which is 2.0f64.powi(53) - 1.0)

Pauan avatar Nov 29 '19 00:11 Pauan