pub fn execute(
    module: &Module,
    compilation: &Compilation,
    instance: &mut Instance,
) -> Result<(), String> {
    let start_index = module
        .start_func
        .ok_or_else(|| String::from("No start function defined, aborting execution"))?;
    // TODO: Put all the function bodies into a page-aligned memory region, and
    // then make them ReadExecute rather than ReadWriteExecute.
    for code_buf in &compilation.functions {
        match unsafe {
            protect(
                code_buf.as_ptr(),
                code_buf.len(),
                Protection::ReadWriteExecute,
            )
        } {
            Ok(()) => (),
            Err(err) => {
                return Err(format!(
                    "failed to give executable permission to code: {}",
                    err
                ))
            }
        }
    }

    let code_buf = &compilation.functions[start_index];

    // Collect all memory base addresses and Vec.
    let mut mem_base_addrs = instance
        .memories
        .iter_mut()
        .map(LinearMemory::base_addr)
        .collect::<Vec<_>>();
    let vmctx = make_vmctx(instance, &mut mem_base_addrs);

    // Rather than writing inline assembly to jump to the code region, we use the fact that
    // the Rust ABI for calling a function with no arguments and no return matches the one of
    // the generated code.Thanks to this, we can transmute the code region into a first-class
    // Rust function and call it.
    unsafe {
        let start_func = transmute::<_, fn(*const *mut u8)>(code_buf.as_ptr());
        start_func(vmctx.as_ptr());
    }
    Ok(())
}
/// Jumps to the code region of memory and execute the start function of the module.
Jumps to the code region of memory and execute the start function of the module.
Jumps to the code region of memory and execute the start function of the module .
pub fn execute(
    module: &Module,
    compilation: &Compilation,
    instance: &mut Instance,
) -> Result<(), String> {
    let start_index = module
        .start_func
        .ok_or_else(|| String::from("No start function defined, aborting execution"))?;
    // TODO: Put all the function bodies into a page-aligned memory region, and
    // then make them ReadExecute rather than ReadWriteExecute.
    for code_buf in &compilation.functions {
        match unsafe {
            protect(
                code_buf.as_ptr(),
                code_buf.len(),
                Protection::ReadWriteExecute,
            )
        } {
            Ok(()) => (),
            Err(err) => {
                return Err(format!(
                    "failed to give executable permission to code: {}",
                    err
                ))
            }
        }
    }
    let code_buf = &compilation.functions[start_index];
    // Collect all memory base addresses and Vec.
    let mut mem_base_addrs = instance
        .memories
        .iter_mut()
        .map(LinearMemory::base_addr)
        .collect::<Vec<_>>();
    let vmctx = make_vmctx(instance, &mut mem_base_addrs);
    // Rather than writing inline assembly to jump to the code region, we use the fact that
    // the Rust ABI for calling a function with no arguments and no return matches the one of
    // the generated code.Thanks to this, we can transmute the code region into a first-class
    // Rust function and call it.
    unsafe {
        let start_func = transmute::<_, fn(*const *mut u8)>(code_buf.as_ptr());
        start_func(vmctx.as_ptr());
    }
    Ok(())
}
pub fn execute ( module : & Module , compilation : & Compilation , instance : & mut Instance , ) -> Result < ( ) , String > { let start_index = module . start_func . ok_or_else ( | | String :: from ( " " ) ) ? ; // TODO: Put all the function bodies into a page-aligned memory region, and // then make them ReadExecute rather than ReadWriteExecute. for code_buf in & compilation . functions { match unsafe { protect ( code_buf . as_ptr ( ) , code_buf . len ( ) , Protection :: ReadWriteExecute , ) } { Ok ( ( ) ) => ( ) , Err ( err ) => { return Err ( format ! ( " " err ) ) } } } let code_buf = & compilation . functions [ start_index ] ; // Collect all memory base addresses and Vec. let mut mem_base_addrs = instance . memories . iter_mut ( ) . map ( LinearMemory :: base_addr ) . collect :: < Vec < _ > > ( ) ; let vmctx = make_vmctx ( instance , & mut mem_base_addrs ) ; // Rather than writing inline assembly to jump to the code region, we use the fact that // the Rust ABI for calling a function with no arguments and no return matches the one of // the generated code.Thanks to this, we can transmute the code region into a first-class // Rust function and call it. unsafe { let start_func = transmute :: < _ , fn ( * const * mut u8 ) > ( code_buf . as_ptr ( ) ) ; start_func ( vmctx . as_ptr ( ) ) ; } Ok ( ( ) ) }
Jumps to the code region of memory and execute the start function of the module.
Jumps to the code region of memory and execute the start function of the module .
module
&Module
compilation
&Compilation
instance
&mut Instance
module
&Module
compilation
&Compilation
instance
&mut Instance