Building A Plugin System with Rust+Wasm
Robert Masen
Slides
https://github.com/freemasen/rbr-wasmer
Repo
https://github.com/freemasen/rbr-plugins
What Is Wasm
- Bytecode
- Needs VM
# #![allow(unused_variables)] #fn main() { #[no_mangle] pub fn double(n: u32) -> u32 { n * 2 } #}
(module
(type $t0 (func (param i32) (result i32)))
(func $double (export "double") (type $t0) (param $p0 i32) (result i32)
(i32.shl
(local.get $p0)
(i32.const 1)))
(table $T0 1 1 funcref)
(memory $memory (export "memory") 16)
(global $g0 (mut i32) (i32.const 1048576))
(global $__data_end (export "__data_end") i32 (i32.const 1048576))
(global $__heap_base (export "__heap_base") i32 (i32.const 1048576)))
- The simplest VM to use right now
Requirements
- Rust (obviously)
- The
wasm32-unknown-unknown
targetrustup target add wasm32-unknown-unknown
- Cmake
- MacOS
brew install cmake
ports install cmake
- Debian/Ubuntu
apt-get install cmake
- FreeBSD
pkg install cmake
- Windows
choco install cmake
- (cmake.org/download)[https://cmake.org/download/]
- MacOS
Wasm's Limitations
- Only knows numbers
Simple Plugin
Code!
Simple Plugin Runner
Code!
Work Arounds
- Remember WASM Only Knows Numbers
- How could we pass/return a String?
Plugin Strings
Memory
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
® | 0 | 0 | 0 | 0 | d | o | u | b | l | e |
# #![allow(unused_variables)] #fn main() { // 0,1,2,3,4, 5 , 6 , 7 , 8 , 9 , 10 let memory = vec![0,0,0,0,0,100,111,117,98 ,108,101]; // ®,0,0.0.0, d , o , u , b , l , e let wi_len = vec![0,0,0,0,6,100,111,117,98 ,108,101]; // [ 6u32 ], d , o , u , b , l , e let double = vec![0,0,0,0,12,100,111,117,98 ,108,101,100,111,117,98 ,108,101] // [ 12u32 ] , d , o , u , b , l , e , d , o , u , b , l , e #}
Code!
with a little unsafe
Runner Strings
Code!
Error Feedback
But what if this goes wrong?
- Import a function from the host
- First Arg always
Context
- First Arg always
Proc Macro
- Attribute Macro
TokenStreams
toTokenStreams
Move the scary bits
Code!
Potental
- What if we wanted to work with even more complicated data?
- Could we use a binary serialization format?
- Bincode
- cbor
- msg-pack