Struct ProgramInstance

Source
pub struct ProgramInstance { /* private fields */ }
Expand description

Program instance. Program is a set of instantiated modules.

Implementations§

Source§

impl ProgramInstance

Source

pub fn new() -> Self

Create new program instance.

Examples found in repository?
examples/interpret.rs (line 18)
9fn main() {
10    let args: Vec<_> = args().collect();
11    if args.len() != 3 {
12        println!("Usage: {} <wasm file> <arg>", args[0]);
13        println!("    wasm file should contain exported `_call` function with single I32 argument");
14        return;
15    }
16
17    // Intrepreter initialization.
18    let program = sophon_wasm::ProgramInstance::new();
19
20    // Here we load module using dedicated for this purpose
21    // `deserialize_file` function (which works only with modules)
22    let module = sophon_wasm::deserialize_file(&args[1]).expect("Failed to load module");
23
24    // Intialize deserialized module. It adds module into It expects 3 parameters:
25    // - a name for the module
26    // - a module declaration
27    // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here
28    // This test shows how to implement native module https://github.com/NikVolf/sophon-wasm/blob/master/src/interpreter/tests/basics.rs#L197
29    let module = program.add_module("main", module, None).expect("Failed to initialize module");
30
31    // The argument should be parsable as a valid integer
32    let argument: i32 = args[2].parse().expect("Integer argument required");
33
34    // "_call" export of function to be executed with an i32 argument and prints the result of execution
35    println!("Result: {:?}", module.execute_export("_call", vec![sophon_wasm::RuntimeValue::I32(argument)].into()));
36}
More examples
Hide additional examples
examples/invoke.rs (line 19)
9fn main() {
10    let args: Vec<_> = args().collect();
11    if args.len() < 3 {
12        println!("Usage: {} <wasm file> <exported func> [<arg>...]", args[0]);
13        return;
14    }
15    let func_name = &args[2];
16    let (_, program_args) = args.split_at(3);
17
18    // Intrepreter initialization.
19    let program = sophon_wasm::ProgramInstance::new();
20
21    let module = sophon_wasm::deserialize_file(&args[1]).expect("File to be deserialized");
22
23    // Extracts call arguments from command-line arguments
24    let execution_params = {
25        // Export section has an entry with a func_name with an index inside a module
26        let export_section = module.export_section().expect("No export section found");
27        // It's a section with function declarations (which are references to the type section entries)
28        let function_section = module.function_section().expect("No function section found");
29        // Type section stores function types which are referenced by function_section entries
30        let type_section = module.type_section().expect("No type section found");
31
32        // Given function name used to find export section entry which contains
33        // an `internal` field which points to the index in the function index space
34        let found_entry = export_section.entries().iter()
35            .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name));
36
37        // Function index in the function index space (internally-defined + imported)
38        let function_index: usize = match found_entry.internal() {
39            &Internal::Function(index) => index as usize,
40            _ => panic!("Founded export is not a function"),
41        };
42
43        // We need to count import section entries (functions only!) to subtract it from function_index
44        // and obtain the index within the function section
45        let import_section_len: usize = match module.import_section() {
46            Some(import) =>
47                import.entries().iter().filter(|entry| match entry.external() {
48                    &External::Function(_) => true,
49                    _ => false,
50                    }).count(),
51            None => 0,
52        };
53
54        // Calculates a function index within module's function section
55        let function_index_in_section = function_index - import_section_len;
56
57        // Getting a type reference from a function section entry
58        let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize;
59
60        // Use the reference to get an actual function type
61        let function_type: &FunctionType = match &type_section.types()[func_type_ref] {
62            &Type::Function(ref func_type) => func_type,
63        };
64
65        // Parses arguments and constructs runtime values in correspondence of their types
66        let args: Vec<RuntimeValue> = function_type.params().iter().enumerate().map(|(i, value)| match value {
67            &ValueType::I32 => RuntimeValue::I32(program_args[i].parse::<i32>().expect(&format!("Can't parse arg #{} as i32", program_args[i]))),
68            &ValueType::I64 => RuntimeValue::I64(program_args[i].parse::<i64>().expect(&format!("Can't parse arg #{} as i64", program_args[i]))),
69            &ValueType::F32 => RuntimeValue::F32(program_args[i].parse::<f32>().expect(&format!("Can't parse arg #{} as f32", program_args[i]))),
70            &ValueType::F64 => RuntimeValue::F64(program_args[i].parse::<f64>().expect(&format!("Can't parse arg #{} as f64", program_args[i]))),
71        }).collect();
72
73        interpreter::ExecutionParams::from(args)
74    };
75
76    // Intialize deserialized module. It adds module into It expects 3 parameters:
77    // - a name for the module
78    // - a module declaration
79    // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here
80    // This test shows how to implement native module https://github.com/NikVolf/sophon-wasm/blob/master/src/interpreter/tests/basics.rs#L197
81    let module = program.add_module("main", module, None).expect("Failed to initialize module");
82
83    println!("Result: {:?}", module.execute_export(func_name, execution_params).expect(""));
84}
Source

pub fn add_module<'a>( &self, name: &str, module: Module, externals: Option<&'a HashMap<String, Arc<dyn ModuleInstanceInterface + 'a>>>, ) -> Result<Arc<ModuleInstance>, Error>

Instantiate module with validation.

Examples found in repository?
examples/interpret.rs (line 29)
9fn main() {
10    let args: Vec<_> = args().collect();
11    if args.len() != 3 {
12        println!("Usage: {} <wasm file> <arg>", args[0]);
13        println!("    wasm file should contain exported `_call` function with single I32 argument");
14        return;
15    }
16
17    // Intrepreter initialization.
18    let program = sophon_wasm::ProgramInstance::new();
19
20    // Here we load module using dedicated for this purpose
21    // `deserialize_file` function (which works only with modules)
22    let module = sophon_wasm::deserialize_file(&args[1]).expect("Failed to load module");
23
24    // Intialize deserialized module. It adds module into It expects 3 parameters:
25    // - a name for the module
26    // - a module declaration
27    // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here
28    // This test shows how to implement native module https://github.com/NikVolf/sophon-wasm/blob/master/src/interpreter/tests/basics.rs#L197
29    let module = program.add_module("main", module, None).expect("Failed to initialize module");
30
31    // The argument should be parsable as a valid integer
32    let argument: i32 = args[2].parse().expect("Integer argument required");
33
34    // "_call" export of function to be executed with an i32 argument and prints the result of execution
35    println!("Result: {:?}", module.execute_export("_call", vec![sophon_wasm::RuntimeValue::I32(argument)].into()));
36}
More examples
Hide additional examples
examples/invoke.rs (line 81)
9fn main() {
10    let args: Vec<_> = args().collect();
11    if args.len() < 3 {
12        println!("Usage: {} <wasm file> <exported func> [<arg>...]", args[0]);
13        return;
14    }
15    let func_name = &args[2];
16    let (_, program_args) = args.split_at(3);
17
18    // Intrepreter initialization.
19    let program = sophon_wasm::ProgramInstance::new();
20
21    let module = sophon_wasm::deserialize_file(&args[1]).expect("File to be deserialized");
22
23    // Extracts call arguments from command-line arguments
24    let execution_params = {
25        // Export section has an entry with a func_name with an index inside a module
26        let export_section = module.export_section().expect("No export section found");
27        // It's a section with function declarations (which are references to the type section entries)
28        let function_section = module.function_section().expect("No function section found");
29        // Type section stores function types which are referenced by function_section entries
30        let type_section = module.type_section().expect("No type section found");
31
32        // Given function name used to find export section entry which contains
33        // an `internal` field which points to the index in the function index space
34        let found_entry = export_section.entries().iter()
35            .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name));
36
37        // Function index in the function index space (internally-defined + imported)
38        let function_index: usize = match found_entry.internal() {
39            &Internal::Function(index) => index as usize,
40            _ => panic!("Founded export is not a function"),
41        };
42
43        // We need to count import section entries (functions only!) to subtract it from function_index
44        // and obtain the index within the function section
45        let import_section_len: usize = match module.import_section() {
46            Some(import) =>
47                import.entries().iter().filter(|entry| match entry.external() {
48                    &External::Function(_) => true,
49                    _ => false,
50                    }).count(),
51            None => 0,
52        };
53
54        // Calculates a function index within module's function section
55        let function_index_in_section = function_index - import_section_len;
56
57        // Getting a type reference from a function section entry
58        let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize;
59
60        // Use the reference to get an actual function type
61        let function_type: &FunctionType = match &type_section.types()[func_type_ref] {
62            &Type::Function(ref func_type) => func_type,
63        };
64
65        // Parses arguments and constructs runtime values in correspondence of their types
66        let args: Vec<RuntimeValue> = function_type.params().iter().enumerate().map(|(i, value)| match value {
67            &ValueType::I32 => RuntimeValue::I32(program_args[i].parse::<i32>().expect(&format!("Can't parse arg #{} as i32", program_args[i]))),
68            &ValueType::I64 => RuntimeValue::I64(program_args[i].parse::<i64>().expect(&format!("Can't parse arg #{} as i64", program_args[i]))),
69            &ValueType::F32 => RuntimeValue::F32(program_args[i].parse::<f32>().expect(&format!("Can't parse arg #{} as f32", program_args[i]))),
70            &ValueType::F64 => RuntimeValue::F64(program_args[i].parse::<f64>().expect(&format!("Can't parse arg #{} as f64", program_args[i]))),
71        }).collect();
72
73        interpreter::ExecutionParams::from(args)
74    };
75
76    // Intialize deserialized module. It adds module into It expects 3 parameters:
77    // - a name for the module
78    // - a module declaration
79    // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here
80    // This test shows how to implement native module https://github.com/NikVolf/sophon-wasm/blob/master/src/interpreter/tests/basics.rs#L197
81    let module = program.add_module("main", module, None).expect("Failed to initialize module");
82
83    println!("Result: {:?}", module.execute_export(func_name, execution_params).expect(""));
84}
Source

pub fn insert_loaded_module( &self, name: &str, module_instance: Arc<dyn ModuleInstanceInterface>, ) -> Result<Arc<dyn ModuleInstanceInterface>, Error>

Insert instantiated module.

Source

pub fn module(&self, name: &str) -> Option<Arc<dyn ModuleInstanceInterface>>

Get one of the modules by name

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Erased for T