Skip to content

Instantly share code, notes, and snippets.

@s-macke
Last active August 28, 2023 06:30
Show Gist options
  • Save s-macke/6dd78c78be46214d418454abb667a1ba to your computer and use it in GitHub Desktop.
Save s-macke/6dd78c78be46214d418454abb667a1ba to your computer and use it in GitHub Desktop.
Hello world example by using an headerless implementation of the WASI interface. The only dependency is clang
/*
* This code is a headerless implementation of the WASI interface in C and prints "Hello World!.
* You only need clang and the llvm linker.
*
* compile with
* clang -Os -nostdlib --target=wasm32 -Wl,--allow-undefined hello.c -o hello.wasm
*
* run with
* https://runno.dev/wasi
* Just upload hello.wasm
*
* https://github.com/wasmerio/wasmer
* wasmer run hello.wasm
*
* https://github.com/CraneStation/wasmtime
* wasmtime hello.wasm
*
* https://github.com/fastly/lucet/wiki/lucetc
* lucetc-wasi hello.wasm -o hello.so && lucet-wasi hello.so
*/
// WASI FD_WRITE FUNCTION DECLARATIONS
// ----------------------------------------------------
// see https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/headers/public/wasi/api.h
// Custom data type definitions
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef long size_t;
typedef uint16_t __wasi_errno_t;
typedef uint32_t __wasi_fd_t;
// Structure to hold the buffer and its length for WASI I/O operations
typedef struct __wasi_ciovec_t {
const void *buf;
size_t buf_len;
} __wasi_ciovec_t;
// Macro to define syscall name for WASI functions
#define __WASI_SYSCALL_NAME(name) \
__attribute__((__import_module__("wasi_snapshot_preview1"), __import_name__(#name)))
// Function prototype for the WASI fd_write function
__wasi_errno_t __wasi_fd_write(
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
size_t *nwritten
) __WASI_SYSCALL_NAME(fd_write);
// UTILITY FUNCTIONS
// ----------------------------------------------------
// Function to return the length of a string
size_t slen(const char *str)
{
const char *char_ptr;
for (char_ptr = str; *char_ptr; ++char_ptr)
;
return (char_ptr - str);
}
// Function to print a string to stdout using the WASI fd_write function
void print(const char *str)
{
const __wasi_fd_t stdout = 1; // File descriptor for stdout
size_t nwritten; // Number of bytes written
__wasi_errno_t error; // Error code returned by WASI function
__wasi_ciovec_t iovec; // I/O vector for WASI write operation
iovec.buf = str;
iovec.buf_len = slen(str);
error =__wasi_fd_write(stdout, &iovec, 1, &nwritten);
}
// MAIN ENTRY POINT
// ----------------------------------------------------
__attribute__((export_name("_start")))
void _start()
{
print("Hello World!\n"); // Print "Hello World!" to stdout
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment