#tools #webassembly #wasm

wabt

Bindings to the wabt library

22 releases (6 breaking)

0.7.4 Jan 14, 2019
0.7.3 Dec 18, 2018
0.7.1 Nov 7, 2018
0.4.0 Jul 2, 2018
0.2.2 Mar 11, 2018

#3 in #webassembly

Download history 1617/week @ 2018-12-20 953/week @ 2018-12-27 2194/week @ 2019-01-03 1274/week @ 2019-01-10 1903/week @ 2019-01-17 1471/week @ 2019-01-24 1434/week @ 2019-01-31 1952/week @ 2019-02-07 1585/week @ 2019-02-14 1157/week @ 2019-02-21 1549/week @ 2019-02-28 1927/week @ 2019-03-07 2263/week @ 2019-03-14 2052/week @ 2019-03-21 2211/week @ 2019-03-28

3,893 downloads per month
Used in 16 crates (15 directly)

Apache-2.0

6.5MB
110K SLoC

C++ 76K SLoC // 0.1% comments Python 23K SLoC // 0.2% comments JavaScript 9K SLoC // 0.1% comments Rust 1.5K SLoC // 0.2% comments C 625 SLoC // 0.1% comments Shell 370 SLoC // 0.6% comments VB6 149 SLoC Batch 5 SLoC // 0.7% comments

WABT bindings for Rust

crates.io docs.rs

Rust bindings for WABT. Work in progress.

Usage

Add this to your Cargo.toml:

[dependencies]
wabt = "0.7.1"

Example

wat2wasm (previously known as wast2wasm):

extern crate wabt;
use wabt::wat2wasm;

fn main() {
    assert_eq!(
        wat2wasm("(module)").unwrap(),
        &[
            0, 97, 115, 109, // \0ASM - magic
            1, 0, 0, 0       //  0x01 - version
        ]
    );
}

wasm2wat:

extern crate wabt;
use wabt::wasm2wat;
fn main() {
    assert_eq!(
        wasm2wat(&[
            0, 97, 115, 109, // \0ASM - magic
            1, 0, 0, 0       //    01 - version
        ]),
        Ok("(module)\n".to_owned()),
    );
}

wabt can be also used for parsing the official testsuite scripts.

use wabt::script::{ScriptParser, Command, CommandKind, Action, Value};
 
let wast = r#"
;; Define anonymous module with function export named `sub`.
(module 
  (func (export "sub") (param $x i32) (param $y i32) (result i32)
    ;; return x - y;
    (i32.sub
      (get_local $x) (get_local $y)
    )
  )
)
 
;; Assert that invoking export `sub` with parameters (8, 3)
;; should return 5.
(assert_return
  (invoke "sub"
    (i32.const 8) (i32.const 3)
  )
  (i32.const 5)
)
"#;
 
let mut parser = ScriptParser::from_str(wast)?;
while let Some(Command { kind, .. }) = parser.next()? { 
    match kind {
        CommandKind::Module { module, name } => {
            // The module is declared as annonymous.
            assert_eq!(name, None);
 
            // Convert the module into the binary representation and check the magic number.
            let module_binary = module.into_vec()?;
            assert_eq!(&module_binary[0..4], &[0, 97, 115, 109]);
        }
        CommandKind::AssertReturn { action, expected } => {
            assert_eq!(action, Action::Invoke { 
                module: None,
                field: "sub".to_string(),
                args: vec![
                    Value::I32(8),
                    Value::I32(3)
                ],
            });
            assert_eq!(expected, vec![Value::I32(5)]);
        },
        _ => panic!("there are no other commands apart from that defined above"),
    }
}

Dependencies