Формат ABI функций WASI
Я создаю среду выполнения Webassembly и в настоящее время реализую API-интерфейсы WASI. Мне интересно, как выглядит ABI согласно этому документу: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md
Для проверки я скомпилировал это приложение C с помощью emscripten в отдельный модуль WASM.
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
После проверки с помощью wasm-objdump я вижу следующие импортированные функции:
Import[2]:
- func[0] sig=2 <__wasi_proc_exit> <- wasi_snapshot_preview1.proc_exit
- func[1] sig=11 <__wasi_fd_write> <- wasi_snapshot_preview1.fd_write
с подписями типа:
- type[2] (i32) -> nil
- type[11] (i32, i32, i32, i32) -> i32
Согласно спецификации, функция имеет подпись
fd_write(fd: fd, iovs: ciovec_array) -> Result<size, errno>
, который соответствует системному вызову POSIX
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
.
Но каков четвертый аргумент в файле WASM? Он получает некий указатель на адрес памяти. Поэтому я подумал, что мне придется написать
Result<size, errno>
на этот адрес, но если я сделаю это и верну 0 (для успеха),
fd_write
вызывается снова и снова (предположительно, потому что функция printf предполагает, что ничего не было написано). Если я верну записанные байты, программа завершится правильно, но каков тогда четвертый аргумент? Кроме того, как я могу вернуть более сложные
Result
s, которые не подходят для i32?
1 ответ
В wasi-libc сигнатура функции
__wasi_fd_read
является:
__wasi_errno_t __wasi_fd_read( __wasi_fd_t fd, const __wasi_iovec_t *iovs, size_t iovs_len, __wasi_size_t *retptr0 )
Согласно некоторым реализациям
fd_write
, последний аргумент — это указатель для возврата количества записанных байтов, а возвращаемое значение всегда равно 0 (как вы сделали).
Поэтому я думаю, вы также должны установить количество прочитанных байтов, где
retptr0
указывает на.