Примитивный тип Webassembly i64 - PullRequest
       190

Примитивный тип Webassembly i64

1 голос
/ 07 августа 2020

В документации по веб-сборке указано , что веб-сборка может принимать только следующие типы

i32 | i64 | f32 | f64

Все хорошо, но вот действительно простой тест на C ++, который берет 4 целых числа и распечатывает их.

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;


}

когда я компилирую и вызываю этот тест в Firefox из java скрипта, например:

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 );

, я получаю следующий результат:

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

почему int64_t - это 3978021347401611945, а не "-1596801628841"? Что здесь происходит? Я определенно передал тип "number" из javascrypt, который был целью метода "parseInt". Но что еще более удивительно, так это то, что uint64_t равен нулю вместо «1596801628841».

Обновление 1-> 08. Август 2020

Я создал очень простой модуль веб-сборки, который имеет только 2 метода т.е. «main» и «intTest»

Весь код можно найти здесь

https://github.com/courteous/wasmInt64Test

здесь можно найти скомпилированный код

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

вы можете запустить его из консоли, например:

emrun --no_browser firefox  --verboise index.htm

, а затем в консоли firefox:

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

, если вы хотите скомпилировать код самостоятельно, запустите

emcmake cmake -DCMAKE_BUILD_TYPE=WASM   ../

Обновление 2 -> 08. Август 2020

с использованием std :: bitset Я напечатал купленные числа, то есть аргумент что я получаю, например, int64TypeArg

11001000 11001011 00111010 10101001 00110111 00110100 11000101 01010111

и статически устанавливаю номер для переменной uint64_t -1596801628841;

11111111 11111111 11111110 10001100 00110111 00110100 11000101 01010111

, поскольку пользователь @harold упомянул, что есть несколько бит, которые совпадают, т.е.

101000110000110111001101001100010101010111

это 42 бита, которые совпадают. Сначала я подумал, что это может быть связано с самым большим целым числом, которое имеет javaScript, т.е. 53 бита, но это 42, а не 53. Я действительно хочу разобраться в этом.

1 Ответ

1 голос
/ 08 августа 2020

ОК, через какое-то время выяснилось, что можно !!! НЕ !!! передать i64 из Java Script в WASM напрямую, не меняя сначала тип этой переменной. Если мы хотим это сделать, нам нужно скомпилировать с флагом «WASM_BIGINT» и передать этот длинный i64 из Java Script как тип «BigInt». пример:

var bigInt = BigInt(-1596801628841);

После этого тест работает нормально! Это работало только с Firefox 79.0, но не работало с Chrome 84.0.4147.105 хорошим блогом, объясняющим, что все это здесь и здесь

...