pywasm
pywasm copied to clipboard
Issues with importing libraries
I am trying to analyse polybench suite (written in C)
Since none of your test files contain any #include, wanted to know what to do in case of such cases.
Used emscripten to comile to .c files to .wasm
On trying to load the file in pyawm using pywasm.load("filename")
Getting the following error:
Exception Traceback (most recent call last)
/usr/local/lib/python3.7/site-packages/pywasm/init.py in load(name, imps) 69 with open(name, 'rb') as f: 70 module = structure.Module.from_reader(f) ---> 71 return VirtualMachine(module, imps) 72 73
/usr/local/lib/python3.7/site-packages/pywasm/init.py in init(self, module, imps) 15 for e in self.module.imports: 16 if e.module not in imps or e.name not in imps[e.module]: ---> 17 raise Exception(f'pywasm: global import {e.module}.{e.name} not found') 18 if e.kind == convention.extern_func: 19 a = execution.HostFunc(self.module.types[e.desc], imps[e.module][e.name])
Exception: pywasm: global import env.calloc not found
For the time being libc is not supported on pywasm("calloc", "memcpy"...). This is related to the positioning of pywasm, which is an interpreter, not a complete operating system.
When it is compiled to wasm, these c functions will act as external dependencies of the wasm module, like:
#include <stdlib.h>
int main() {
char *str = calloc(10, 10);
return str;
}
(module
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(import "env" "calloc" (func $calloc (param i32 i32) (result i32))) <---------- HERE! HERE! HERE!
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "main" (func $main))
(func $main (; 1 ;) (result i32)
(call $calloc
(i32.const 10)
(i32.const 10)
)
)
)
So you may need static compilation (I'm not sure weather it worked) or a libc's wasm implementation.
But at the same time pywasm provides a way for you to implement libc's functions yourself, The above code can be run with:
import pywasm
def calloc(ctx: pywasm.Ctx, n: int, size: int):
s = ctx.mems[0].size - 1
ctx.mems[0].grow(n * size)
return s
vm = pywasm.load("/tmp/program.wasm", imps={'env': {
'calloc': calloc
}})
r = vm.exec('main', [])
print(r)
Thanks. I found some workaround in emcc compilation :
emcc -static
Which reduces the number of imports in the code. The corresponding file.wat is:
(module
(type (;0;) (func (param i32 i32 i32) (result i32)))
(type (;1;) (func (param i32 f64 i32 i32 i32 i32) (result i32)))
(type (;2;) (func (param i32 i32)))
(type (;3;) (func (param i32 i64 i32) (result i64)))
(import "wasi_unstable" "fd_close" (func (;0;) (type 4)))
(import "wasi_unstable" "fd_write" (func (;1;) (type 5)))
(import "env" "__syscall140" (func (;2;) (type 6)))
(import "wasi_unstable" "proc_exit" (func (;3;) (type 8)))
.....
.....
All these compilations are for the polybench suite 4.1 compiled using emscripten
As per this link __syscall140 corresponds to env.fd_seek.
So for the following descriptors, these are all functions from wasi. Will implementing their corresponding libc functions be sufficient for the same?
Well, in fact it (WASI) is in my TODO list. It has been delayed for too long
See #25
So at the moment, you may not run this test on pywasm, sorry.