Типы данных: всего четыре числа
Изучаем числовые типы Wasm и понимаем, почему их так мало.
Базовые типы Wasm — это
i32,i64,f32,f64: два целых и два с плавающей точкой, по 32 и 64 бита.
Четыре типа — и всё
Если вы привыкли к десяткам типов из C++ или Java, аскетизм Wasm удивит. На уровне ядра у Wasm всего четыре числовых типа:
| Тип | Что это | Аналог в C |
i32 | 32-битное целое | int |
i64 | 64-битное целое | long long |
f32 | 32-битное число с плавающей точкой | float |
f64 | 64-битное число с плавающей точкой | double |
А где строки, массивы, булевы?
Их на этом уровне нет — и это сделано намеренно. WebAssembly спроектирован максимально близко к тому, что умеет реальный процессор, а процессор знает только целые и дробные числа разной ширины. Всё остальное — надстройка:
- Булево — это
i32: 0 значит «ложь», любое ненулевое — «истина». - Символы и байты — это
i32с маленьким значением (например, код символа). - Строки и массивы — это последовательности байт в линейной памяти; через границу передают адрес (
i32) и длину (i32). - Знаковость не хранится в типе:
i32— просто 32 бита. Знаковое или нет — решает конкретная инструкция (i32.div_sпротивi32.div_u).
Знаковые и беззнаковые операции
Тип i32 один, а вот операций над ним две версии — со знаком (_s, signed) и без (_u, unsigned). Сравним деление на JS-модели, где это видно явно при работе с большими беззнаковыми значениями.
const bits = 0xFFFFFFFF; // все 32 бита единицы
console.log("как unsigned:", bits >>> 0); // 4294967295
console.log("как signed:", bits | 0); // -1
Вывод:
как unsigned: 4294967295 как signed: -1
Одни и те же 32 бита читаются как 4294967295 или как -1 — всё зависит от того, какой операцией мы их трактуем. Ровно так же устроен i32 в Wasm.
Как работает под капотом
Малое число типов делает Wasm-движок простым и быстрым. Валидатору легко проверить, что в f64.add приходят два f64, а не строки. Компилятору легко отобразить четыре типа Wasm на регистры процессора, которые ровно эти четыре формы и поддерживают. Чем меньше сущностей, тем меньше места для ошибок и тем выше предсказуемость.
Частые ошибки в понимании
- «В Wasm есть тип string» — нет, строка живёт в памяти как байты, через границу идёт адрес и длина.
- «i32 — это знаковое число» — i32 это просто 32 бита; знаковость определяет инструкция (_s или _u).
- «Нужно использовать i64 для надёжности» — i64 тяжелее на 32-битных платформах; берите i32, если значения помещаются.
Итоги
- Базовых типов всего четыре: i32, i64, f32, f64.
- Булево, символы, флаги — это i32; строки и массивы — байты в памяти.
- Знаковость не в типе, а в инструкции (_s / _u).
- Минимализм типов даёт простую валидацию и быструю компиляцию.