Crate to represent wasm in Rust?
Is there any package to represent the parts of WebAssembly in Rust?
Ideally I'd build up an abstract syntax structure in memory, then parse is to either text (wat) of binary (wasm). The representation can either map 1-to-1 to wasm, or something fairly close.
The closest I've found is Binaryens format, but I prefer native Rust. It doesn't seem very hard to make, but even easier if it's already done.
EDIT Sorry for the slow response, I made a MWE to show what I mean.
I'd like to write something like this in Rust:
let param_n = Parameter::new(Name::new("n".to_owned()).unwrap(), Type::Int32);
let var_n = param_n.local();
let loop_condition_decl =
DeclareLocal::new(Name::new("loop_condition".to_owned()).unwrap(), Type::Bool);
let loop_condition = loop_condition_decl.local();
let fac_result_decl =
DeclareLocal::new(Name::new("fac_result".to_owned()).unwrap(), Type::Int32);
let fac_result = fac_result_decl.local();
let loop_name = Name::new("fac_loop".to_owned()).unwrap();
let mut the_loop = Loop::new_named(
loop_name.clone(),
vec![
Statement::Assign(Assign::new(
fac_result.clone(),
Expression::Mul(Mul::new(
Expression::Local(fac_result.get()),
Expression::Local(var_n.get()),
)),
)),
Statement::Assign(Assign::new(
loop_condition.clone(),
Expression::Gt(Gt::new(
Expression::Local(var_n.get()),
Expression::Const(Const::new(Type::Int32, Value::Int(2))),
)),
)),
Statement::Assign(Assign::new(
var_n.clone(),
Expression::Add(Add::new(
Expression::Local(var_n.get()),
Expression::Const(Const::new(Type::Int32, Value::Int(-1))),
)),
)),
],
);
let loop_label = the_loop.label();
the_loop.add(Statement::BranchIf(BranchIf::new(
Expression::Local(loop_condition.get()),
loop_label,
)));
let wasm = Module::new(vec![Function::new(
Name::new("fac".to_owned()).unwrap(),
vec![param_n],
vec![Output::new(Type::Int32)],
Group::new(vec![
// Function body
Statement::Local(fac_result_decl),
Statement::Local(loop_condition_decl),
Statement::Assign(Assign::new(
fac_result.clone(),
Expression::Const(Const::new(Type::Int32, Value::Int(1))),
)),
// Statement::Block(Block::new_named("".to_owned(), vec![])),
Statement::Loop(the_loop),
Statement::Return(Return::new(Expression::Local(fac_result.get()))),
]),
)]);
println!("{}", wasm.as_wat());
Which'd then produce this:
(module
(func $fac (export "fac") (param $n i32) (result i32)
(local $fac_result i32)
(local $loop_condition i32)
i32.const 1
set_local $fac_result
loop $fac_loop
get_local $fac_result
get_local $n
i32.mul
set_local $fac_result
get_local $n
i32.const 2
i32.gt_s
set_local $loop_condition
get_local $n
i32.const -1
i32.add
set_local $n
get_local $loop_condition
br_if $fac_loop
end ;; loop $fac_loop
get_local $fac_result
) ;; func $fac
) ;; module
So the Rust type system makes sure the syntax and some of the semantics are correct. It's much easier to manipulate this structure than it is for text.
Does a library like that already exist? It's not very hard to make, but it's a lot of typing, and I'm sure someone smarter will do it somewhat better.