exports/
exports.rs

1// This examples allow to query all function exports of the
2// provided wasm module
3
4extern crate sophon_wasm;
5
6use std::env::args;
7
8use sophon_wasm::elements::{Internal, External, Type, FunctionType, Module};
9
10// Auxillary function to resolve function type (signature) given it's callable index
11fn type_by_index(module: &Module, index: usize) -> FunctionType {
12
13    // Demand that function and type section exist. Otherwise, fail with a
14    // corresponding error.
15    let function_section = module.function_section().expect("No function section found");
16    let type_section = module.type_section().expect("No type section found");
17
18    // This counts the number of _function_ imports listed by the module, excluding
19    // the globals, since indexing for actual functions for `call` and `export` purposes
20    // includes both imported and own functions. So we actualy need the imported function count
21    // to resolve actual index of the given function in own functions list.
22    let import_section_len: usize = match module.import_section() {
23            Some(import) =>
24                import.entries().iter().filter(|entry| match entry.external() {
25                    &External::Function(_) => true,
26                    _ => false,
27                    }).count(),
28            None => 0,
29        };
30
31    // Substract the value queried in the previous step from the provided index
32    // to get own function index from which we can query type next.
33    let function_index_in_section = index - import_section_len;
34
35    // Query the own function given we have it's index
36    let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize;
37
38    // Finally, return function type (signature)
39    match type_section.types()[func_type_ref] {
40        Type::Function(ref func_type) => func_type.clone(),
41    }
42}
43
44fn main() {
45
46    // Example executable takes one argument which must
47    // refernce the existing file with a valid wasm module
48    let args: Vec<_> = args().collect();
49    if args.len() < 2 {
50        println!("Prints export function names with and their types");
51        println!("Usage: {} <wasm file>", args[0]);
52        return;
53    }
54
55    // Here we load module using dedicated for this purpose
56    // `deserialize_file` function (which works only with modules)
57    let module = sophon_wasm::deserialize_file(&args[1]).expect("File to be deserialized");
58
59    // Query the export section from the loaded module. Note that not every
60    // wasm module obliged to contain export section. So in case there is no
61    // any export section, we panic with the corresponding error.
62    let export_section = module.export_section().expect("No export section found");
63
64    // Process all exports, leaving only those which reference the internal function
65    // of the wasm module
66    let exports: Vec<String> = export_section.entries().iter()
67        .filter_map(|entry|
68            // This is match on export variant, which can be function, global,table or memory
69            // We are interested only in functions for an example
70            match *entry.internal() {
71                // Return function export name (return by field() function and it's index)
72                Internal::Function(index) => Some((entry.field(), index as usize)),
73                _ => None
74            })
75        // Another map to resolve function signature index given it's internal index and return
76        // the printable string of the export
77        .map(|(field, index)| format!("{:}: {:?}", field, type_by_index(&module, index).params())).collect();
78
79    // Print the result
80    for export in exports {
81        println!("{:}", export);
82    }
83}