Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webassembly i64 primitive type

The webassembly documentation states that webassembly can take only following types

i32 | i64 | f32 | f64

All good but , here is a really simple test in c++ that takes 4 integers and print them.

void intTest(
        int32_t int32TypeArg,
        uint32_t uint32TypeArg,
        int64_t int64TypeArg,
        uint64_t uint64TypeArg
    ){
    std::cout << " int32_t     :" << to_string(int32TypeArg) << std::endl;
    std::cout << " uint32_t    :" << to_string(uint32TypeArg) << std::endl;
    std::cout << " int64_t     :" << to_string(int64TypeArg) << std::endl;
    std::cout << " uint64_t    :" << to_string(uint64TypeArg) << std::endl;


}

when i compile and call this test in Firefox from java script like that:

let js_int32_t = -1;
let js_uint32_t = 1;

let js_int64_t = -1596801628841;
let js_uint64_t = 1596801628841;



let val1 = parseInt(js_int32_t );
let val2 = parseInt(js_uint32_t );
let val3 = parseInt(js_int64_t );
let val4 = parseInt(js_uint64_t );

i get the following output:

Module._intTest( val1, val2, val3, val4);
 int32_t     :-1 
 uint32_t    :1 
 int64_t     :-3978021347401611945 
 uint64_t    :0 

why int64_t is 3978021347401611945 and not "-1596801628841" ? What is going on here? I definetelly passed a type "number" form javascrypt that was the purpouse of "parseInt" method. But what is even more supprising is that uint64_t is zero instead of "1596801628841".

Update 1-> 08. August 2020

I have created a very simple webassembly module that has only 2 methods i.e. „main“ and „intTest“

The whole code can be found here

https://github.com/courteous/wasmInt64Test

the compiled code can be found here

https://github.com/courteous/wasmInt64Test/tree/master/build/src

you can run it from the console like:

emrun --no_browser firefox  --verboise index.htm

and then in the firefox console:

Module._intTest( js_int32_t, js_uint32_t, js_int64_t, js_uint64_t);

if you want to compile the code yourself run

emcmake cmake -DCMAKE_BUILD_TYPE=WASM   ../

Update 2 -> 08. August 2020

using std::bitset i printed bought numbers i.e. the argument that i get i.e. int64TypeArg

11001000 11001011 00111010 10101001 00110111 00110100 11000101 01010111

and statically setting setting the number to a uint64_t variable -1596801628841;

11111111 11111111 11111110 10001100 00110111 00110100 11000101 01010111

as the user @harold mentioned there are several bits that match i.e.

101000110000110111001101001100010101010111

those are 42 bits that match. At first i was thinking that this could be related to the largest integer that javaScript has i.e. 53 bits , but those are 42 not 53. I really want to get to the bottom of this.

like image 814
Tito Avatar asked Oct 17 '25 06:10

Tito


1 Answers

OK after some time it came out that you can !!! NOT !!! pass i64 from Java Script to WASM directly without changing the type of that variable first. If we want to do that we need to compile with the flag "WASM_BIGINT" and pass the that long i64 from Java Script as the type "BigInt". example :

var bigInt = BigInt(-1596801628841);

After that the test is working properly! This worked only with Firefox 79.0 but did not worked with Chrome 84.0.4147.105 good blog explaining all this is here and here

like image 142
Tito Avatar answered Oct 18 '25 22:10

Tito



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!