• Stars
    star
    467
  • Rank 93,935 (Top 2 %)
  • Language
    C
  • License
    Other
  • Created over 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

WebAssembly interpreter in C

wac - WebAssembly in C

A Minimal WebAssembly interpreter written in C. Supports the WebAssembly MVP (minimum viable product) version of the WebAssembly specification.

There are three different builds of wac:

  • wac: (WebAssembly in C) Minimal client with an interactive REPL mode. Designed to run standalone wasm files compiled with wat2wasm or wasm-as. Passes most spec tests apart from some multi-module import/export tests.
  • wax: (WebAssembly in C with WASI) Client with WebAssembly System Interface APIs (WASI).
  • wace: (WebAssembly in C with Emscripten) Client with host library/memory integration. Designed to run wasm code that has been built with Emscripten (using -s SIDE_MODULE=1 -s LEGALIZE_JS_FFI=0).

Prerequisites

To build wac/wax/wace you need a 32-bit version of gcc and 32-bit versions of SDL2 and libedit. On 64-bit Ubuntu/Debian these can be installed like this:

dpkg --add-architecture i386
apt-get update
apt-get install lib32gcc-4.9-dev libSDL2-dev:i386 libedit-dev:i386

To compile wat source files to binary wasm modules you will need the wasm-as program from Binaryen. To compile C programs to wasm modules you will need Binaryen and emscripten.

As an alternative to downloading and building the above tools, the kanaka/wac docker image (1.7GB) has 32-bit gcc compiler/libraries, emscripten, and binaryen preinstalled. The docker image can be started with appropriate file mounts like this:

docker run -v `pwd`:/wac -w /wac -it kanaka/wac bash

All the build commands below can be run within the docker container.

wac usage

Build wac:

$ make wac

Use wasm-as to compile a simple wat program to a wasm:

$ make examples_wat/arith.wasm

Now load the compiled wasm file and invoke some functions:

$ ./wac examples_wat/arith.wasm add 2 3
0x5:i32
$ ./wac examples_wat/arith.wasm mul 7 8
0x38:i32

wac also supports a very simple REPL (read-eval-print-loop) mode that runs commands in the form of FUNC ARG...:

$ ./wac --repl examples_wat/arith.wasm
> sub 10 5
0x5:i32
> div 13 4
0x3:i32

wax usage

Build wax:

$ make wax

Use wasm-as to compile a wat program that uses the WASI interface:

$ make examples_wat/echo.wasm

Now run the compiled wasm file. The program reads text from stdin and echos it to stdout until an EOF (Ctrl-D) is sent.

$ ./wax examples_wat/echo.wasm
> foo
foo
> bar
bar
> <Ctrl-D>

wace usage

Build wace:

$ make wace

Use emscripten/binaryen to compile some simple C programs and run them using wace:

$ make examples_c/hello1.wasm
$ ./wace examples_c/hello1.wasm
hello world

$ make examples_c/hello2.wasm
$ ./wace examples_c/hello2.wasm
hello malloc people

Use emscripten/binaryen to compile some C SDL programs and run them using wace:

$ make examples_c/hello_sdl.wasm
$ ./wace examples_c/hello_sdl.wasm
INFO: OpenGL shaders: ENABLED
INFO: Created renderer: opengl
# Blue Window displayed for 2 seconds
Done.

$ make examples_c/triangle.wasm
$ ./wace examples_c/triangle.wasm
# A colorfully shaded triangle is rendered

Running WebAssembly spec tests

wac includes a runtest.py test driver which can be used for running tests from the WebAssembly specification.

Check out the spec:

git clone https://github.com/WebAssembly/spec

You will need wat2wasm to compile the spec tests. Check-out and build wabt (wabbit):

git clone --recursive https://github.com/WebAssembly/wabt
make -C wabt gcc-release

Run the func.wast test file (to test function calls) from the spec:

./runtest.py --wat2wasm ./wabt/out/gcc/Release/wat2wasm --interpreter ./wac spec/test/core/func.wast

Run all the spec tests apart from a few that currently fail (mostly due to runtest.py missing support for some syntax used in those test files):

BROKE_TESTS="comments exports imports linking names data elem inline-module"
for t in $(ls spec/test/core/*.wast | grep -Fv "${BROKE_TESTS// /$'\n'}"); do
    echo -e "\nTESTING ${t}"
    ./runtest.py ${t} || break
done

Standalone Builds using Fooboot

wac and wace can be built to run as standalone bootable programs using fooboot:

cd wac
git clone https://github.com/kanaka/fooboot
make PLATFORM=fooboot clean
make PLATFORM=fooboot wac wace examples_wat/addTwo.wasm

The fooboot/runfoo script can be used to boot wac/wace with QEMU. fooboot/runfoo also creates a connection on a serial port (COM2) that allows files to be read from the host system:

fooboot/runfoo wac --repl examples_wat/addTwo.wasm
QEMU waiting for connection on: disconnected:tcp:localhost:21118,server
webassembly> addTwo 2 3
0x5:i32

The standalone wac/wace builds can also be built into an ISO image that can boot directly on real hardware. You will need Grub 2 and the Grub PC/BIOS binary files (grub-pc-bin) and the xorriso program to be able to do this. Also, the wasm modules that you wish to run must be built into the binary to become part of a simple in-memory file-system:

echo "examples_wat/addTwo.wasm" > mem_fs_files
make PLATFORM=fooboot \
     FOO_TARGETS="wac" \
     FOO_CMDLINE="examples_wat/addTwo.wasm addTwo 3 4" \
     boot.iso

You can now boot the ISO with QEMU like this:

qemu-system-i386 -cdrom boot.iso

Or you can burn the ISO to a USB device and boot from it on real hardware. This will destroy any data on the USB device! Also, make completely sure that /dev/MY_USB_DEVICE is really the USB device you want to overwrite and not your hard drive. You have been warned!

sudo dd if=boot.iso of=/dev/MY_USB_DEVICE && sync
# Now boot you can boot from the USB device

License

MPL-2.0 (see LICENSE).

More Repositories

1

mal

mal - Make a Lisp
Assembly
9,969
star
2

miniMAL

A Delightfully Diminutive Lisp. Implemented in < 1 KB of JavaScript with JSON source, macros, tail-calls, JS interop, error-handling, and more.
JavaScript
629
star
3

raft.js

Raft.js is an implementation of the Raft consensus algorithm in JavaScript and using WebRTC.
TeX
319
star
4

warpy

WebAssembly interpreter in RPython
Python
65
star
5

wam

WebAssembly Macro language and processor
JavaScript
63
star
6

libvncserver

Fork of libvncserver with support for tightPng encoding
C
62
star
7

pascal.js

Pascal compiler implemented in JavaScript
JavaScript
43
star
8

Diet-noVNC

noVNC (HTML5 VNC client) without the sugar
JavaScript
41
star
9

instacheck

Property-based testing with inputs defined as EBNF grammars
Clojure
28
star
10

fooboot

boot your foo (build and boot your program in QEMU or on real hardware)
C
26
star
11

mal.workshop

Mal Workshop for LambdaConf 2016
Makefile
18
star
12

rbt_cfs

Red-Black Tree and Completely Fair Scheduler Simulation and Visualization
JavaScript
17
star
13

spacewar

Spacewar arcade game using python and pygame/SDL
Python
13
star
14

OpenVPN-LDAP-Integration

OpenVPN certification management and LDAP/Active Directory based authorization scripts
Python
12
star
15

bartender

Automated testing of browser rendering engines using Clojure, generative (property-based) testing, formal grammars (EBNF), and a consensus test oracle.
Clojure
10
star
16

html5-css3-ebnf

Convert W3C HTML5 and CSS3 spec data to EBNF formal grammars
Clojure
8
star
17

chaocipher

Chaocipher: Javascript and Python versions
Python
7
star
18

noVNC-js1k

A VNC client in 1K of JavaScript (for the 2012 js1k.com competition)
Python
7
star
19

Scriptany

Use any language within script tags
JavaScript
6
star
20

Horton

Optimized Conway's Game of Life Engine in C
C
3
star
21

lambdaconf

Reveal.js presentation materials for LambdaConf Workshop
JavaScript
3
star
22

HTML5

HTML5 Presentation
3
star
23

30queens

Minimal 30 Queens
C
3
star
24

strangeloop2018

JavaScript
2
star
25

kanaka.github.com

User website repo
2
star
26

cmProject

Configuration Management System using make and subversion
2
star
27

webutils

A collection of small and useful webapps
2
star
28

SelectList

A Javascript library for creating a mouse/touch selectable group of DOM elements.
JavaScript
2
star
29

auto.mk

Simpler makefiles: auto.mk without automake.
1
star
30

static

Static files for bartender
CSS
1
star
31

hashpipe.js

HashPipe.js: hash sync with pipes
JavaScript
1
star
32

cmProject_example

An example project using cmProject and auto.mk together
C
1
star
33

cljs-in-cljs-presentation

Clojure/West 2013 ClojureScript-in-ClojureScript Presentation
JavaScript
1
star
34

fuzzy-raft

Raft.js with Dynamic Leader heartbeat / election timer using Fuzzy Logic
TeX
1
star