Skip to content

Instantly share code, notes, and snippets.

@sunfishcode
Created February 25, 2017 00:47
Show Gist options
  • Save sunfishcode/78c6a752d60ee84410e9f8fbeb0d0291 to your computer and use it in GitHub Desktop.
Save sunfishcode/78c6a752d60ee84410e9f8fbeb0d0291 to your computer and use it in GitHub Desktop.
wasm object stuff
Here's some C code:
void extern_func(int *, int*, int*, int*);
static int static_var = 3;
int global_var = 4;
extern int extern_var;
__attribute__((noinline))
static void static_func(void)
{
static_var = 5;
}
void normal_func(void)
{
int stack_var;
extern_func(&stack_var, &static_var, &global_var, &extern_var);
static_func();
}
Compile it like: clang --target=wasm32-unknown-unknown-wasm -O2 -c t.c
Running wasm2wast on the t.o file currently doesn't work, because LLVM's relocation records
differ a little from wabt's, but if I manually remove those sections for now, wasm2wast
prints the following. I've annotated it with some comments.
(module
(type (;0;) (func))
(type (;1;) (func (param i32 i32 i32 i32)))
(import "env" "extern_var" (global (;0;) i32)) ;; a global import; the global isn't actually used; this just provides an index for use in relocation
(import "env" "extern_func" (func extern_func (type 1))) ;; a function import; this is actually used, in addition to being used for relocations
(func normal_func (type 0)
(local i32)
get_global 0 ;; read the stack pointer
i32.const 16
i32.sub
tee_local 0
set_global 0 ;; write the stack pointer (our local copy is in local 0)
get_local 0
i32.const 12
i32.add ;; stack_var (local 0 holds the stack pointer value. plus an offset)
i32.const 0 ;; static_var; the 0 is the actual linear memory offset within this module, but we also have a reloc so we can link it with other modules
i32.const 4 ;; global_var; the 4 is ... ditto ...
i32.const -1 ;; extern_var; the -1 is a placeholder the linker will need to patch
call extern_func
call static_func
get_local 0
i32.const 16
i32.add
set_global 0) ;; restore the original stack pointer value
(func static_func (type 0)
i32.const 0
i32.const 5
i32.store)
(table (;0;) 0 anyfunc) ;; this module has no literal function addresses, so the table is empty (that may change if this module is linked with other modules)
(memory (;0;) 8)
(global (;1;) (mut i32) (i32.const 0)) ;; the stack-pointer global
(global (;2;) i32 (i32.const 4)) ;; global_var's global (when the new-and-improved name section arrives, we'll be able to name this instead of just calling it "0" everywhere)
(export "normal_func" (func normal_func)) ;; a normal function export
(export "global_var" (global 2)) ;; an export of the global for global_var
(data (i32.const 0) "\03\00\00\00\04\00\00\00")) ;; the data containing static_var and then global_var
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment