Skip to content

Commit a344a65

Browse files
authored
Merge pull request #13 from gparmer/master
First draft of the Documentation
2 parents 64ab86d + 4199351 commit a344a65

File tree

6 files changed

+1234
-12
lines changed

6 files changed

+1234
-12
lines changed

README.md

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
aWsm
1+
aWsm - An Awesome Wasm Compiler and Runtime
22
==========
33

44
# What is aWsm?
@@ -32,25 +32,82 @@ Please have patience as we update those to `awsm`.
3232

3333
## Why aWsm?
3434

35-
Why would we implement a Wasm compiler and runtime.
35+
Why would we implement a Wasm compiler and runtime?
3636
The Web Assembly eco-system is still developing, and we see the need for a system focusing on:
3737

3838
- *Performance.*
3939
aWsm is an ahead-of-time compiler that leverages the LLVM compiler to optimize code, and target different architectural backends.
40-
We have evaluated the compiler on x86-64, aarch64 (Raspberry Pi), ARM Cortex-M7 (and M4), and performance on the microprocessors is within 10% of native, and within 40% on the microcontrollers.
40+
We have evaluated aWsm on x86-64, aarch64 (Raspberry Pi), and thumb (ARM Cortex-M4 and M7), and performance on the microprocessors is within 10% of native, and within 40% on the microcontrollers on Polybench benchmarks.
4141
- *Simplicity.*
4242
The entire code base for the compiler and runtime is relatively small.
4343
The compiler is <3.5K lines of Rust, and the runtime (for *all* platforms) is <5K lines of C.
4444
It is nearly trivial to implement different means of sandboxing memory accesses.
4545
We've implemented *seven* different mechanisms for this!
4646
- *Portability.*
4747
Both the compiler and runtime are mostly platform-independent code, and porting to a new platform only really requires additional work if you need to tweak stack sizes (microcontrollers), or use architectural features (e.g., MPX, segmentation, etc...).
48+
aWsm only links what is needed, so it's possible to avoid microcontroller-expensive operations such as f64, f32, and even dynamic memory.
49+
- *Composability.*
50+
The final output of aWsm is simple `*.o` elf objects that can be linked into larger systems.
51+
This enables the trivial composition of sandboxes together, and sandboxes into larger programs.
4852

49-
We believe that aWsm is one of the best options for ahead-of-time compilation for outside of the browser.
53+
We believe that aWsm is one of the best options for ahead-of-time compilation for Wasm execution outside of the browser.
54+
55+
If you want to learn more about aWsm, see the [design](doc/design.md), or the [publication](https://www2.seas.gwu.edu/~gparmer/publications/emsoft20wasm.pdf).
5056

5157
# Performance
5258

53-
Give us a little time, we'll post benchmarks here!
59+
PolyBench/C benchmarks for **x86-64** (slowdown over native C):
60+
61+
| | Wasmer | WAVM | Node.js + Emscripten | Lucet | aWsm |
62+
| --- | --- | --- | --- | --- | --- |
63+
| Avg. Slowdown | 149.8% | 28.1% | 84.0% | 92.8% | 13.4% |
64+
| Stdev. in Slowdown | 194.09 | 53.09 | 107.84 | 117.25 | 34.65 |
65+
66+
PolyBench/C benchmarks for **Arm aarch64** (slowdown over native C):
67+
68+
| | aWsm |
69+
| --- | --- |
70+
| Avg. Slowdown | 6.7% |
71+
| Stdev. of Slowdown | 19.38 |
72+
73+
Polybench/C benchmarks for **Arm Cortex-M** microcontrollers (slowdown over native C):
74+
75+
| Architectures | aWsm |
76+
| --- | --- |
77+
| Cortex-M7 Avg. slowdown | 40.2% |
78+
| Cortex-M4 Avg. slowdown | 24.9% |
79+
80+
In comparison, the [`wasm3` interpreter's slowdown](https://github.com/wasm3/wasm3/blob/master/docs/Performance.md) on microcontrollers is more than 10x.
81+
For more details (including other bounds checking mechanisms), see the [paper](https://www2.seas.gwu.edu/~gparmer/publications/emsoft20wasm.pdf).
82+
83+
*Note: these numbers are from May 2020.*
84+
85+
There are many compelling runtimes, but we believe that aWsm is useful in generating very fast code, while being simple and extensible.
86+
87+
## Comparison to Existing Wasm Ecosystems
88+
89+
There are many existing compilers and runtimes.
90+
aWsm fills the niche of a compiler
91+
92+
- based on ahead-of-time compilation using the popular LLVM infrastructure,
93+
- that generates fast, safe code (even on microcontrollers), and
94+
- that is designed for to be lightweight and easily extended.
95+
96+
Adding runtime functions and changing safety checking mechanisms are trivial operations.
97+
98+
| Runtime | Method | x86_64 | x86 | aarch64 | thumb | URL |
99+
| --- | --- | --- | --- | --- | --- | --- |
100+
| aWsm | AoT ||||| You are here |
101+
| Wasmtime | AoT |||| | https://github.com/bytecodealliance/wasmtime |
102+
| Wasmer | AoT |||| | https://github.com/wasmerio/wasmer |
103+
| WAMR | Pseudo-AoT/Int ||||| https://github.com/bytecodealliance/wasm-micro-runtime |
104+
| Wasm3 | Int ||||| https://github.com/wasm3/wasm3 |
105+
| Wasmi | Int ||||| https://github.com/paritytech/wasmi |
106+
107+
This is not an exhaustive list!
108+
There are many others as this is a pretty active area.
109+
110+
*Note: this table is from the best of our understanding of each system in July 2020.*
54111

55112
# Getting started!
56113

@@ -88,12 +145,6 @@ cd awsm
88145

89146
The compiler can now be run via `silverfish`
90147

91-
The tests can run with
92-
93-
```
94-
cd code_benches; python run.py
95-
```
96-
97148
### Other Systems
98149

99150
1. [Install Rust](https://www.rust-lang.org/tools/install)
@@ -113,6 +164,42 @@ cargo build --release
113164
```
114165
6. The awsm binary is built at `target/release/silverfish`. Copy this to the appropriaate place for your platform and add to your PATH if neccessary.
115166

167+
## Executing and Testing aWsm
168+
169+
The tests can run with
170+
171+
```sh
172+
cd code_benches; python run.py
173+
```
174+
175+
Please see the [design](doc/design.md) to understand the pipeline, and see `run.py` for an example of how to connect existing compilers (to generate Wasm, and generate machine code from LLVM IR) with aWsm.
176+
177+
Note that aWsm is still a research prototype, so might have some rough edges.
178+
It is not currently turn-key.
179+
You likely need to understand how to generate Wasm, and use an LLVM compile chain.
180+
We're happy to accept PRs with fixes, and "quality of life" improvements.
181+
182+
We're in the processes of standing up a CI infrastructure.
183+
184+
## Tour of the Source
185+
186+
The source is organized as such:
187+
188+
- `src/` - the Rust source of the compiler, and the `silverfish` binary.
189+
Look here for the logic for taking in Wasm, and generating LLVM bytecode.
190+
`cargo` guides the compilation of this code.
191+
- `code_benches/` - This is a relatively large set of benchmarks, many of which are derived from Polybench (`pb_*`), MiBench (`mb_*`), or various applications (`custom_*` including NN inference, sqlite, a PID controller, and an extended Kalman filter).
192+
The `run.py` file guides the compilation and execution of these as effectively a set of unit tests, and is an example of the compilation structure of an application with the runtime in aWsm.
193+
- `example_code/` - More atomic tests for specific Wasm features (bounds checks, indirect function invocations, etc...).
194+
This ensures that changes to the compiler don't break Wasm sandboxing, and provides regression tests.
195+
- `runtime/` - The aWsm runtime.
196+
This includes most of the code that provides the sandboxing guarantees (for example, including bounds checks, indirect function call type checks and indirection).
197+
Microcontroller-specific runtime code (for Arm Cortex-M processors) referred to in [`eWasm`](https://www2.seas.gwu.edu/~gparmer/publications/emsoft20wasm.pdf), is in `cortex_m_glue/` and `libc/cortex_m_backing.c`.
198+
Various pluggable bounds checks can be found in `runtime/memory/`.
199+
The runtime is compiled separately, and combined with the LLVM IR output by aWsm (using LTO) to generate the final sandboxed object.
200+
- `doc/` - Documentation directory.
201+
See the `*.md` files there.
202+
116203
# Limitations and Assumptions
117204

118205
*Additional Wasm instruction support needed.*
@@ -131,7 +218,7 @@ We provide details in Section 7 of our [EMSOFT publication](https://www2.seas.gw
131218
We believe that some changes to the specification, or the creation of an embedded profile might be warranted.
132219
The main limitations:
133220

134-
1. *Invariant page size.*
221+
1. *Variant page sizes selected by the runtime.*
135222
Wasm uses 64KiB pages.
136223
That is far too large for embedded systems.
137224
aWsm uses smaller pages, while simulating the larger default pages.
@@ -145,3 +232,12 @@ The main limitations:
145232
3. *Allow undefined behavior on Out of Bounds (OoB) accesses.*
146233
The specification requires any access outside of the allocated bounds of linear memory to be caught, and the sandbox terminated.
147234
We show in the publication that relaxing this requirement, and allowing undefined behavior on OoB accesses can significantly speed up execution, and shrink code sizes, while maintaining strong sandboxed isolation.
235+
236+
# About Us & Acknowledgments
237+
238+
The GWU Systems group focuses on low-level system design and implementation.
239+
One of our main research vehicles is the [Composite](composite.seas.gwu.edu) component-based operating system, which we aim to integrate with Wasm through aWsm.
240+
If you're interested in low-level hacking and system building, in secure and reliable systems, in embedded systems, or in models for parallelism, don't hesitate to contact [Gabe](www.seas.gwu.edu/~gparmer) about doing a PhD or becoming involved with the group.
241+
242+
Our collaborations with Arm Research during a lot of the maturation of the aWsm infrastructure have been instrumental in its development.
243+
Support from SRC, ARM, and NSF have all contributed greatly to Wasm's research.

doc/design.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# aWsm Design
2+
3+
Here we briefly discuss the design of aWsm.
4+
The intent isn't to be exhaustive, rather to give you a high-level understanding of the system.
5+
For the gory details, see the [publication](https://www2.seas.gwu.edu/~gparmer/publications/emsoft20wasm.pdf).
6+
7+
# Background: Wasm Sandbox
8+
9+
![The layout of a Wasm sandbox.](layout.png)
10+
11+
Wasm uses a co-design between the compiler, and the dynamic checks of the runtime system to provide the sandbox that isolates the surrounding system from the logic of the contained code.
12+
The figure depicts the main aspects of the sandbox.
13+
These include:
14+
15+
- *Linear memory* that holds all memory accessed by the sandbox.
16+
The compiler emits code that checks that all loads and stores remain within the linear memory, thus preventing errant accesses outside the sandbox.
17+
Linear memory is expandable much like a traditional heap.
18+
- The *indirect function call table* that facilitates function pointer calls.
19+
To ensure that function pointer invocations are safe (to code generated by the compiler), function pointers reference an *offset* into the table.
20+
Each entry includes the type of the function, and ensures that function invocations are well-typed.
21+
- The separation of the *execution stack* -- used to track function calls -- and the *data stack* -- used to contain stack-allocated data that can be referenced, thus must be in linear memory.
22+
23+
The first of these ensures the proper memory isolation of the sandbox, while the latter two provide control-flow integrity of the sandbox.
24+
25+
# aWsm Processing Pipeline
26+
27+
![The lifecycle of the aWsm compiler as applied to the embedded Wasm (Arm Cortex-M) runtime.](overview.png)
28+
29+
This picture depicts the aWsm pipeline.
30+
31+
- Programming languages are compiled into Wasm, for example, using LLVM.
32+
- Wasm has a binary representation and (as depicted) a s-expr representation.
33+
- The aWsm compiler inputs binary Wasm, generates LLVM IR corresponding to the Wasm.
34+
- This IR is compiled with the runtime to generate the final object that exports `wasm_main` to execute in the broader application.
35+
36+
In the Figure, we target Arm Cortex-M, and the yellow boxes emphasize how linear memory bounds checks transition throughout the process.
37+
38+
# aWsm Runtime
39+
40+
aWsm implements all safety checks in the runtime (in C).
41+
This maximizes the portability and extensibility of the system, and we've used this to prototype multiple bounds check implementations (see the discussion of three of these in the [paper](https://www2.seas.gwu.edu/~gparmer/publications/emsoft20wasm.pdf)).
42+
To enable this, the compiler generates LLVM IR that calls the runtime for common operations including loading and storing in linear memory.
43+
We rely on the Link-Time Optimization (LTO) of LLVM to remove the boundaries between executable and runtime.
44+
Similarly, indirect function calls (function pointer invocations) are implemented within the C of the runtime.
45+
46+
aWsm uses a [`musl`](https://musl.libc.org/) libc implementation (by default), and we interpose on the system calls by instead converting them to calls to the runtime.
47+
In this way, system calls can be sanitized, constrained, or transformed by the runtime.
48+
WASI support is of significant interest, but is not yet enabled.

doc/layout.png

34.7 KB
Loading

doc/layout.svg

Lines changed: 1 addition & 0 deletions
Loading

doc/overview.png

132 KB
Loading

0 commit comments

Comments
 (0)