К сожалению, я не могу получить рабочий инструментарий для компиляции C / C ++ в файл wasm, но я надеялся, что здесь поможет мне добрая душа. Учитывая фрагмент программы:
struct foo {
int a;
float b;
};
void function(foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
foo(&my_foo);
}
для чего нужен код wasm my_program
выглядит как?
Я собираюсь предположить, что вы имеете в виду, как выглядит текстовый формат отходов?
Я настроил пару вещей в вашем коде, чтобы он компилировался:
struct foo {
int a;
float b;
};
extern void bar(struct foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
bar(&my_foo);
}
Компилируем его с помощью emscripten / binaryen, а затем с помощью wasm2wast:
emcc -s WASM=1 -s SIDE_MODULE=1 -O2 str.c -o str.js
wasm-dis str.wasm -o str.wast
Обратите внимание, что без -s SIDE_MODULE=1 -O2
emscripten извлекает набор стандартной библиотеки (malloc и т. д.), а файл wast имеет длину 10000 строк. Я предполагаю, что вы, вероятно, просто хотите довольно простой результат wasm / wast без всех связей / включений.
Это приводит к следующему файлу:
(module
(type $0 (func (param i32)))
(type $1 (func))
(import "env" "memoryBase" (global $import$0 i32))
(import "env" "_bar" (func $import$1 (param i32)))
(import "env" "memory" (memory $0 256))
(import "env" "table" (table 0 anyfunc))
(import "env" "tableBase" (global $import$4 i32))
(global $global$0 (mut i32) (i32.const 0))
(global $global$1 (mut i32) (i32.const 0))
(export "_my_program" (func $0))
(export "__post_instantiate" (func $2))
(export "runPostSets" (func $1))
(func $0 (type $1)
(local $var$0 i32)
(local $var$1 i32)
(block $label$0
(set_local $var$0
(get_global $global$0)
)
(set_global $global$0
(i32.add
(get_global $global$0)
(i32.const 16)
)
)
(i32.store
(tee_local $var$1
(get_local $var$0)
)
(i32.const 1)
)
(f32.store offset=4
(get_local $var$1)
(f32.const -3)
)
(call $import$1
(get_local $var$1)
)
(set_global $global$0
(get_local $var$0)
)
)
)
(func $1 (type $1)
(nop)
)
(func $2 (type $1)
(block $label$0
(set_global $global$0
(get_global $import$0)
)
(set_global $global$1
(i32.add
(get_global $global$0)
(i32.const 5242880)
)
)
(call $1)
)
)
;; custom section "dylink", size 5
)
Обратите внимание, что memoryBase
, tableBase
, __post_instantiate
, а также runPostSets
emscripten дополнения для интеграции / инициализации памяти платформы. memoryBase
в основном начало стека C и значение копируется __post_instantiate
в $global$0
(который является глобальным для всех функций в этом модуле). когда my_program
вызывается первым делом, когда мы корректируем указатель стека на 16, чтобы указать, где компилятор «выделил» пространство для структуры my_foo в стеке. Теперь мы делаем пару i32.store
операции с использованием offset=X
обновить поля внутри foo
, Когда функция возвращается, мы восстанавливаем указатель стека ($global$0
), где это было, когда мы вошли в функцию.
Других решений пока нет …