Почему файлы WASM разные?

Я хочу использовать WebAssembly, поэтому мне нужно скомпилировать файл C в файл WASM.

Содержимое файла C следующее

//The online 'add.c'
WASM_EXPORT
int add(int a, int b)
{ 
    return a + b;
}

Это очень простой файл C.

Этот файл WASM компилируется онлайн-инструментами компиляции https://webassembly.studio/. Я использую инструмент wasm2wat, чтобы разобрать его в текстовый файл, и его содержимое выглядит следующим образом

(module
 (type $t0 (func))
 (type $t1 (func (param i32 i32) (result i32)))
 (func $__wasm_call_ctors (type $t0))
 (func $add (type $t1) (param $p0 i32) (param $p1 i32) (result i32)
   local.get $p1
   local.get $p0
   i32.add)
 (table $T0 1 1 funcref)
 (memory $memory 2)
 (global $g0 (mut i32) (i32.const 66560))
 (global $__heap_base i32 (i32.const 66560))
 (global $__data_end i32 (i32.const 1024))
 (export "memory" (memory 0))
 (export "__heap_base" (global 1))
 (export "__data_end" (global 2))
 (export "add" (func $add)))

И я также использую "emcc add.c -s WASM=1 -O3 -o add.js" для компиляции локального "add.c"

//The local 'add.c'
EMSCRIPTEN_KEEPALIVE
int add(int a, int b)
{
    return a + b;
}

Файл WASM, полученный с помощью приведенной выше команды,

(module
 (type $t0 (func))
 (type $t1 (func (param i32 i32) (result i32)))
 (func $b (type $t0)
   nop)
 (func $c (type $t1) (param $p0 i32) (param $p1 i32) (result i32)
   local.get $p0
   local.get $p1
   i32.add)
 (table $a 1 1 funcref)
 (export "a" (table 0))
 (export "b" (func $b))
 (export "c" (func $c)))

Почему два результата различаются? Почему указанный выше файл можно использовать в HTML, а не следующий?

1 ответ

Это два немного разных драйвера компилятора (хотя оба основаны на llvm+clang), и они нацелены на несколько разные среды. ABI/API/ контракт с устройством для внедрения несколько отличаются. Например, в emscripten контракт по умолчанию заключается в том, что объект памяти WebAssembly создается в JS и экспортируется в файл WebAssembly. По умолчанию для WASI (wasm за пределами сети) создается объект памяти в файле wasm и экспортируется во встраивающее устройство (отсюда и экспорт "памяти" в вашем первом случае).

Некоторые из этих лишних элементов в вашем первом примере, вероятно, будут удалены, запустив wasm-optна результирующем выходе. Например, если в вашем крошечном примере ни память, ни таблица не используются, теоретически их можно полностью удалить.

Другие вопросы по тегам