Skip to content

lesleyrs/wasmlite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wasmlite - like emscripten but less magical

This project makes use of JSPI which is able to suspend/resume wasm execution which avoids the need to export functions to call them from JS. Combined with pdclib allows for porting some desktop programs to run in the browser with little changes.

This requires a modern chrome version or javascript.options.wasm_js_promise_integration enabled in firefox.

Usage

CC = clang --target=wasm32 --sysroot=/path/to/wasm/libc
LDFLAGS += -nodefaultlibs -lc -lm # avoids system path libclang_rt.builtins-wasm32.a, or `-nostdlib -Dmain=_start -lc -lm` for no crt1 as well
LDFLAGS += -Wl,--export-table # for function pointers access in JS, such as for event listeners
LDFLAGS += -Wl,--export=malloc # for JS functions that allocate internally (JS_openFilePicker/glGetString)
LDFLAGS += -Wl,--stack-first # to fail fast on stack overflow, else it will quietly overwrite data
LDFLAGS += -Wl,-z,stack-size=value # increase stack size

more options: https://lld.llvm.org/WebAssembly.html

To have clangd work create a compile_flags.txt file with the same flags as CC

  1. run make html > /path/to/project/index.html (or make js) to bundle/minify libjs
  2. run a http server esbuild --servedir=. and pass program name + args similar to CLI /?program&arg 1&arg 2 in the url.

Builtin key shortcuts are alt+enter for fullscreen toggle, shift+enter for image scaling toggle, Chrome performance drops with dev console open.

Porting C programs

  1. add wasm platform to the codebase or just replace SDL, use #include <js/glue.h> to have access to JS functions
  2. pdclib doesn't implement posix, see musl for implementations
  3. call JS_setTimeout(ms) or JS_requestAnimationFrame() in any long running loops (main loop, ones waiting for input or http requests)

wasm sourcemaps (Chrome only):

https://medium.com/oasislabs/webassembly-debugging-bec0aa93f8c6

build your program with -g -O0 and optionally -lc-dbg instead of -lc for better stack traces

git clone https://github.com/emscripten-core/emscripten.git
../emscripten/tools/wasm-sourcemap.py out.wasm -w out.wasm -p $(CURDIR) -s -u ./out.wasm.map -o out.wasm.map --dwarfdump=/usr/bin/llvm-dwarfdump

or

llvm-dwarfdump -a out.wasm > out.wasm.dwarf
../emscripten/tools/wasm-sourcemap.py out.wasm -w out.wasm -p $(CURDIR) -s -u ./out.wasm.map -o out.wasm.map --dwarfdump-output=out.wasm.dwarf

If your systems llvm-dwarfdump isn't compatible with the latest wasm-sourcemap.py, you can also use emsdk/upstream/bin/llvm-dwarfdump.

After this chrome will automatically load the sourcemap linked in the modified wasm file.

Optional:

experimental:

  • wcc: alternative to clang+wasm-ld but lacking goto, no dwarf debuginfo and may have other issues compiling. use /path/to/wcc -isystem=/path/to/libc/include -L/path/to/libc/lib -Wl,--export-table --stack-size=amount.

Limitations

  • no proper file modes for writing/appending files etc, use JS_saveFile(). For sockets you have to use the functions in websocket.h
  • WIP: webgl2, TODO: webgpu/webworker + some events: touch/gamepad/glctx loss+restore etc https://developer.mozilla.org/en-US/docs/Web/Events
  • no compiler-rt which is required for use of long doubles etc: if you provide this to clang you won't need to pass -nodefaultlibs -lc but it has to be placed in system path? Without this you may get undefined symbol errors especially with -lc-dbg (some uses of ld have been swapped for doubles)

Ports

In some forks the non-wasm targets haven't been kept in a working state, and most programs don't support saves load/download yet

These emulators are not so accurate but still serve as examples

About

ported libc + browser libjs for webassembly

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors