WebAssembly i64 原始类型

Tit*_*ito 4 c++ webassembly c++17

WebAssembly 文档指出WebAssembly 只能采用以下类型

\n
i32 | i64 | f32 | f64\n
Run Code Online (Sandbox Code Playgroud)\n

一切都很好,但是,这是一个非常简单的 C++ 测试,它需要 4 个整数并打印它们。

\n
void intTest(\n        int32_t int32TypeArg,\n        uint32_t uint32TypeArg,\n        int64_t int64TypeArg,\n        uint64_t uint64TypeArg\n    ){\n    std::cout << " int32_t     :" << to_string(int32TypeArg) << std::endl;\n    std::cout << " uint32_t    :" << to_string(uint32TypeArg) << std::endl;\n    std::cout << " int64_t     :" << to_string(int64TypeArg) << std::endl;\n    std::cout << " uint64_t    :" << to_string(uint64TypeArg) << std::endl;\n\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当我在 Firefox 中从 java 脚本编译并调用这个测试时,如下所示:

\n
let js_int32_t = -1;\nlet js_uint32_t = 1;\n\nlet js_int64_t = -1596801628841;\nlet js_uint64_t = 1596801628841;\n\n\n\nlet val1 = parseInt(js_int32_t );\nlet val2 = parseInt(js_uint32_t );\nlet val3 = parseInt(js_int64_t );\nlet val4 = parseInt(js_uint64_t );\n
Run Code Online (Sandbox Code Playgroud)\n

我得到以下输出:

\n
Module._intTest( val1, val2, val3, val4);\n int32_t     :-1 \n uint32_t    :1 \n int64_t     :-3978021347401611945 \n uint64_t    :0 \n
Run Code Online (Sandbox Code Playgroud)\n

为什么 int64_t 是 3978021347401611945 而不是“-1596801628841”?这里发生了什么?我明确地从 javascrypt 传递了一个类型“number”,这是“parseInt”方法的目的。 \n但更令人惊讶的是 uint64_t 为零而不是“1596801628841”。

\n

更新 1-> 2020 年 8 月 8 日

\n

我创建了一个非常简单的 WebAssembly 模块,它只有 2 个方法,即 \xe2\x80\x9emain\xe2\x80\x9c 和 \xe2\x80\x9eintTest\xe2\x80\x9c

\n

完整代码可以在这里找到

\n

https://github.com/courteous/wasmInt64Test

\n

编译后的代码可以在这里找到

\n

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

\n

您可以从控制台运行它,例如:

\n
emrun --no_browser firefox \xc2\xa0--verboise index.htm\n
Run Code Online (Sandbox Code Playgroud)\n

然后在 Firefox 控制台中:

\n
Module._intTest( js_int32_t, js_uint32_t, js_int64_t, js_uint64_t);\n
Run Code Online (Sandbox Code Playgroud)\n

如果你想自己编译代码运行

\n
emcmake cmake -DCMAKE_BUILD_TYPE=WASM \xc2\xa0\xc2\xa0../\n
Run Code Online (Sandbox Code Playgroud)\n

更新 2 -> 2020 年 8 月 8 日

\n

使用 std::bitset 我打印了购买的数字,即我得到的参数,即 int64TypeArg

\n
11001000 11001011 00111010 10101001 00110111 00110100 11000101 01010111\n
Run Code Online (Sandbox Code Playgroud)\n

并静态设置将数字设置为 uint64_t 变量-1596801628841;

\n
11111111 11111111 11111110 10001100 00110111 00110100 11000101 01010111\n
Run Code Online (Sandbox Code Playgroud)\n

正如用户 @harold 提到的,有几个位与 ie 匹配

\n
101000110000110111001101001100010101010111\n
Run Code Online (Sandbox Code Playgroud)\n

这些是匹配的 42 位。起初我认为这可能与 javaScript 具有的最大整数即 53 位有关,但那些是 42 而不是 53。\n我真的很想弄清楚这一点。

\n

Tit*_*ito 5

好吧,过了一段时间后发现你可以!不是 !!!直接将 i64 从 Java Script 传递到 WASM,无需先更改该变量的类型。如果我们想这样做,我们需要使用标志“WASM_BIGINT”进行编译,并将那么长的 i64 从 Java 脚本作为类型“BigInt”传递。例子 :

var bigInt = BigInt(-1596801628841);
Run Code Online (Sandbox Code Playgroud)

之后测试就可以正常运行了!这仅适用于 Firefox 79.0,但不适用于 Chrome 84.0.4147.105 解释这一切的好博客 在这里这里