Struct binaryen::Module
[−]
[src]
pub struct Module { /* fields omitted */ }
Modules contain lists of functions, imports, exports, function types.
Methods
impl Module
[src]
fn new() -> Module
[src]
Create a new empty Module.
fn read(wasm_buf: &[u8]) -> Module
[src]
Deserialize a module from binary form.
unsafe fn from_raw(raw: BinaryenModuleRef) -> Module
[src]
fn auto_drop(&self)
[src]
Auto-generate drop() operations where needed. This lets you generate code without worrying about where they are needed.
It is more efficient to do it yourself, but simpler to use autodrop.
fn optimize(&self)
[src]
Run the standard optimization passes on the module.
fn is_valid(&self) -> bool
[src]
Validate a module, printing errors to stdout on problems.
fn print(&self)
[src]
Print a module to stdout in s-expression text format. Useful for debugging.
fn write(&self) -> Vec<u8>
[src]
Serialize a module into binary form.
Examples
let module = Module::new(); let wasm = module.write();
fn set_start(&self, fn_ref: &FnRef)
[src]
Set start function. One per module.
See http://webassembly.org/docs/modules/#module-start-function.
fn set_memory<'a, I, N>(
&self,
initial: u32,
maximal: u32,
name: Option<N>,
segments: I
) where
I: IntoIterator<Item = Segment<'a>>,
N: ToCStr,
[src]
&self,
initial: u32,
maximal: u32,
name: Option<N>,
segments: I
) where
I: IntoIterator<Item = Segment<'a>>,
N: ToCStr,
Set memory to be used by this module.
See http://webassembly.org/docs/modules/#linear-memory-section
Examples
let module = Module::new(); // Create a segment from data and offset. Read more in `Segment` documentation. let data = b"Hello world\0"; let offset_expr = module.const_(Literal::I32(0)); let segment = Segment::new(data, offset_expr); // Set memory definition, also exporting it with name "mem". module.set_memory(1, 1, Some("mem"), vec![segment]); assert!(module.is_valid());
fn relooper(&self) -> Relooper
[src]
fn add_fn_type<N: ToCStr>(
&self,
name: Option<N>,
param_tys: &[ValueTy],
result_ty: Ty
) -> FnType
[src]
&self,
name: Option<N>,
param_tys: &[ValueTy],
result_ty: Ty
) -> FnType
Add a new function type.
If name
is None, name will be autogenerated.
Examples
let module = Module::new(); // Roughly (u32, u64) -> (). let viI = module.add_fn_type(Some("viI"), &[ValueTy::I32, ValueTy::I64], Ty::None);
fn add_fn<N: ToCStr>(
&self,
name: N,
fn_ty: &FnType,
var_tys: &[ValueTy],
body: Expr
) -> FnRef
[src]
&self,
name: N,
fn_ty: &FnType,
var_tys: &[ValueTy],
body: Expr
) -> FnRef
Add a new function.
You can declare variables by passing types of that variables into var_tys
.
Examples
let module = Module::new(); // Add a new function type (u32, u32) -> u32. let params = &[ValueTy::I32, ValueTy::I32]; let iii = module.add_fn_type(Some("iii"), params, Ty::I32); // Load parameter x (local 0) and y (local 1) and do the addition. let x = module.get_local(0, ValueTy::I32); let y = module.get_local(1, ValueTy::I32); let add = module.binary(BinaryOp::AddI32, x, y); // Finally add a new function. let adder = module.add_fn("adder", &iii, &[], add);
fn add_global<N: ToCStr>(&self, name: N, ty: ValueTy, mutable: bool, init: Expr)
[src]
Add a new global.
See http://webassembly.org/docs/modules/#global-section
Examples
let module = Module::new(); let init_expr = module.const_(Literal::I32(0)); module.add_global("counter", ValueTy::I32, true, init_expr);
fn add_fn_import<N1: ToCStr, N2: ToCStr, N3: ToCStr>(
&self,
internal_name: N1,
external_module_name: N2,
external_base_name: N3,
fn_ty: &FnType
)
[src]
&self,
internal_name: N1,
external_module_name: N2,
external_base_name: N3,
fn_ty: &FnType
)
Add a function import.
Examples
let module = Module::new(); // Add a new function type () -> (). let vv = module.add_fn_type(None::<&str>, &[], Ty::None); // Add function called "_abort" from the module "env". // This module can call this function via name "abort". module.add_fn_import("abort", "env", "_abort", &vv);
fn add_fn_export<N1: ToCStr, N2: ToCStr>(
&self,
internal_name: N1,
external_name: N2
)
[src]
&self,
internal_name: N1,
external_name: N2
)
Add a function export.
Examples
let module = Module::new(); // Create a simple function that does nothing. let vv = module.add_fn_type(None::<&str>, &[], Ty::None); let nop = module.nop(); let do_nothing = module.add_fn("do_nothing", &vv, &[], nop); // Export "do_nothing" function with an external name "_do_nothing". module.add_fn_export("do_nothing", "_do_nothing");
fn if_(&self, condition: Expr, if_true: Expr, if_false: Option<Expr>) -> Expr
[src]
Evaluate condition
, and if condition
yields non-zero value if_true
is executed.
If condition
yielded zero value and if_false
is not None
then if_false
is executed.
fn loop_<N: ToCStr>(&self, name: N, body: Expr) -> Expr
[src]
Evaluate body
.
Loop provides a name which can be used together with break_
to make a loop.
Breaking to a loop will transfer control at the start of the loop,
which is roughly equivalent to continue
statement.
Examples
let module = Module::new(); let break_to_loop = module.break_("loop1", None, None); let infinite_loop = module.loop_("loop1", break_to_loop);
fn break_<N: ToCStr>(
&self,
name: N,
condition: Option<Expr>,
value: Option<Expr>
) -> Expr
[src]
&self,
name: N,
condition: Option<Expr>,
value: Option<Expr>
) -> Expr
fn switch<N1: ToCStr, N2: ToCStr>(
&self,
names: Vec<N1>,
default_name: N2,
condition: Expr,
value: Option<Expr>
) -> Expr
[src]
&self,
names: Vec<N1>,
default_name: N2,
condition: Expr,
value: Option<Expr>
) -> Expr
Examples
let module = Module::new(); let condition = module.const_(Literal::I32(2)); let switch = module.switch(vec!["block", "loop"], "default", condition, None);
fn block<N, I>(&self, name: Option<N>, children: I, ty: Option<Ty>) -> Expr where
I: IntoIterator<Item = Expr>,
N: ToCStr,
[src]
I: IntoIterator<Item = Expr>,
N: ToCStr,
Evaluate each node in children
one by one.
You can provide type of this block via ty
, otherwise type would be figured out for you.
Blocks may have names. Branch targets in the IR are resolved by name (as opposed to nesting depth in WebAssembly). This is the only IR node that has a variable-length list of operands.
Examples
let module = Module::new(); let children = vec![module.nop()]; let block = module.block(Some("b1"), children, Some(Ty::None));
Breaking to a block will transfer control past the end of the block.
// This will transfer control after the `b1` block. let br = module.break_("b1", None, None);
fn const_(&self, literal: Literal) -> Expr
[src]
Yield specified literal.
fn load(
&self,
bytes: u32,
signed: bool,
offset: u32,
align: u32,
ty: ValueTy,
ptr: Expr
) -> Expr
[src]
&self,
bytes: u32,
signed: bool,
offset: u32,
align: u32,
ty: ValueTy,
ptr: Expr
) -> Expr
Evaluate ptr
, load value of type ty
at the address
provided by ptr
offseted by offset
.
fn store(
&self,
bytes: u32,
offset: u32,
align: u32,
ptr: Expr,
value: Expr,
ty: ValueTy
) -> Expr
[src]
&self,
bytes: u32,
offset: u32,
align: u32,
ptr: Expr,
value: Expr,
ty: ValueTy
) -> Expr
Evaluate ptr
and value
, store value
at the address
provided by ptr
offseted by offset
.
fn get_global<N: ToCStr>(&self, name: N, ty: ValueTy) -> Expr
[src]
Load value from a global with a specified name.
fn set_global<N: ToCStr>(&self, name: N, value: Expr) -> Expr
[src]
Evaluate value
and store that value to a global with a specified name.
fn get_local(&self, index: u32, ty: ValueTy) -> Expr
[src]
Load value from a local with a specified index.
Note that function parameters and variables share a single locals index space, so if a function has one parameter then it would be at index 0 and first variable would be at index 1.
fn set_local(&self, index: u32, value: Expr) -> Expr
[src]
Evaluate value
and store that value into a local with a specified index.
Note that function parameters and variables share a single locals index space, so if a function has one parameter then it would be at index 0 and first variable would be at index 1.
fn tee_local(&self, index: u32, value: Expr) -> Expr
[src]
Like set_local
but also returns the value
.
fn return_(&self, value: Option<Expr>) -> Expr
[src]
Return control from the current function, optionally returning value
.
fn call<N, I>(&self, name: N, operands: I, ty: Ty) -> Expr where
N: ToCStr,
I: IntoIterator<Item = Expr>,
[src]
N: ToCStr,
I: IntoIterator<Item = Expr>,
Evaluate all operands one by one and then call function defined in the current module.
fn call_import<N, I>(&self, name: N, operands: I, ty: Ty) -> Expr where
N: ToCStr,
I: IntoIterator<Item = Expr>,
[src]
N: ToCStr,
I: IntoIterator<Item = Expr>,
Evaluate all operands one by one and then call imported function.
fn call_indirect<N, I>(&self, target: Expr, operands: I, ty_name: N) -> Expr where
N: ToCStr,
I: IntoIterator<Item = Expr>,
[src]
N: ToCStr,
I: IntoIterator<Item = Expr>,
fn binary(&self, op: BinaryOp, lhs: Expr, rhs: Expr) -> Expr
[src]
Evaluate lhs
, then rhs
and then do a binary operation with them.
Examples
let module = Module::new(); let x = module.get_local(0, ValueTy::I32); let y = module.const_(Literal::I32(3)); let mul_by_3 = module.binary(BinaryOp::MulI32, x, y);
fn unary(&self, op: UnaryOp, value: Expr) -> Expr
[src]
Evaluate value
and then do a unary operation with it.
Examples
let module = Module::new(); let x = module.get_local(0, ValueTy::F64); let square_root = module.unary(UnaryOp::SqrtF64, x);
fn host<N, I>(&self, op: HostOp, name: Option<N>, operands: I) -> Expr where
N: ToCStr,
I: IntoIterator<Item = Expr>,
[src]
N: ToCStr,
I: IntoIterator<Item = Expr>,
fn nop(&self) -> Expr
[src]
No operation, no effect.
fn unreachable(&self) -> Expr
[src]
Instruction that always traps and have type of unreachable
.
This has an interesting consequences on the type system, for example:
(func $test (result i32) (call $return_i64 (unreachable) ) )
Function test
is expected to return i32, but it calls some function that returns i64.
Passing unreachable
as argument to a function makes this function to
also have unreachable
type.
Because unreachable
is a bottom type (i.e. can be used in
place every other type) this example is perfectly valid.
fn select(&self, condition: Expr, if_true: Expr, if_false: Expr) -> Expr
[src]
Evaluate if_true
, if_false
and then condition
.
Exprsession if_true
and if_false
should have the same type as each other.
The value of if_true
returned if condition evaluated to non-zero,
or the value of if_false
otherwise.
fn drop(&self, value: Expr) -> Expr
[src]
Evaluate value
and discard it.