pub fn invoke(
    compiler: &mut Compiler,
    instance: &mut Instance,
    function_name: &str,
    args: &[RuntimeValue],
) -> Result<ActionOutcome, ActionError> {
    let (address, signature, callee_vmctx) = match instance.lookup(function_name) {
        Some(Export::Function {
            address,
            signature,
            vmctx,
        }) => (address, signature, vmctx),
        Some(_) => {
            return Err(ActionError::Kind(format!(
                "exported item \"{}\" is not a function",
                function_name
            )))
        }
        None => {
            return Err(ActionError::Field(format!(
                "no export named \"{}\"",
                function_name
            )))
        }
    };

    for (index, value) in args.iter().enumerate() {
        assert_eq!(value.value_type(), signature.params[index].value_type);
    }

    // TODO: Support values larger than u64. And pack the values into memory
    // instead of just using fixed-sized slots.
    let value_size = mem::size_of::<u64>();
    let mut values_vec: Vec<u64> = vec![0; max(signature.params.len(), signature.returns.len())];

    // Store the argument values into `values_vec`.
    for (index, arg) in args.iter().enumerate() {
        unsafe {
            let ptr = values_vec.as_mut_ptr().add(index);

            match arg {
                RuntimeValue::I32(x) => ptr::write(ptr as *mut i32, *x),
                RuntimeValue::I64(x) => ptr::write(ptr as *mut i64, *x),
                RuntimeValue::F32(x) => ptr::write(ptr as *mut u32, *x),
                RuntimeValue::F64(x) => ptr::write(ptr as *mut u64, *x),
            }
        }
    }

    // Get the trampoline to call for this function.
    let exec_code_buf = compiler
        .get_trampoline(address, &signature, value_size)
        .map_err(ActionError::Setup)?;

    // Make all JIT code produced thus far executable.
    compiler.publish_compiled_code();

    // Call the trampoline.
    if let Err(message) = unsafe {
        wasmtime_call_trampoline(
            exec_code_buf,
            values_vec.as_mut_ptr() as *mut u8,
            callee_vmctx,
        )
    } {
        return Ok(ActionOutcome::Trapped { message });
    }

    // Load the return values out of `values_vec`.
    let values = signature
        .returns
        .iter()
        .enumerate()
        .map(|(index, abi_param)| unsafe {
            let ptr = values_vec.as_ptr().add(index);

            match abi_param.value_type {
                ir::types::I32 => RuntimeValue::I32(ptr::read(ptr as *const i32)),
                ir::types::I64 => RuntimeValue::I64(ptr::read(ptr as *const i64)),
                ir::types::F32 => RuntimeValue::F32(ptr::read(ptr as *const u32)),
                ir::types::F64 => RuntimeValue::F64(ptr::read(ptr as *const u64)),
                other => panic!("unsupported value type {:?}", other),
            }
        })
        .collect();

    Ok(ActionOutcome::Returned { values })
}
/// Invoke a function in an `Instance` identified by an export name.
Invoke a function in an `Instance` identified by an export name.
Invoke a function in an ` Instance ` identified by an export name .
pub fn invoke(
    compiler: &mut Compiler,
    instance: &mut Instance,
    function_name: &str,
    args: &[RuntimeValue],
) -> Result<ActionOutcome, ActionError> {
    let (address, signature, callee_vmctx) = match instance.lookup(function_name) {
        Some(Export::Function {
            address,
            signature,
            vmctx,
        }) => (address, signature, vmctx),
        Some(_) => {
            return Err(ActionError::Kind(format!(
                "exported item \"{}\" is not a function",
                function_name
            )))
        }
        None => {
            return Err(ActionError::Field(format!(
                "no export named \"{}\"",
                function_name
            )))
        }
    };
    for (index, value) in args.iter().enumerate() {
        assert_eq!(value.value_type(), signature.params[index].value_type);
    }
    // TODO: Support values larger than u64. And pack the values into memory
    // instead of just using fixed-sized slots.
    let value_size = mem::size_of::<u64>();
    let mut values_vec: Vec<u64> = vec![0; max(signature.params.len(), signature.returns.len())];
    // Store the argument values into `values_vec`.
    for (index, arg) in args.iter().enumerate() {
        unsafe {
            let ptr = values_vec.as_mut_ptr().add(index);
            match arg {
                RuntimeValue::I32(x) => ptr::write(ptr as *mut i32, *x),
                RuntimeValue::I64(x) => ptr::write(ptr as *mut i64, *x),
                RuntimeValue::F32(x) => ptr::write(ptr as *mut u32, *x),
                RuntimeValue::F64(x) => ptr::write(ptr as *mut u64, *x),
            }
        }
    }
    // Get the trampoline to call for this function.
    let exec_code_buf = compiler
        .get_trampoline(address, &signature, value_size)
        .map_err(ActionError::Setup)?;
    // Make all JIT code produced thus far executable.
    compiler.publish_compiled_code();
    // Call the trampoline.
    if let Err(message) = unsafe {
        wasmtime_call_trampoline(
            exec_code_buf,
            values_vec.as_mut_ptr() as *mut u8,
            callee_vmctx,
        )
    } {
        return Ok(ActionOutcome::Trapped { message });
    }
    // Load the return values out of `values_vec`.
    let values = signature
        .returns
        .iter()
        .enumerate()
        .map(|(index, abi_param)| unsafe {
            let ptr = values_vec.as_ptr().add(index);
            match abi_param.value_type {
                ir::types::I32 => RuntimeValue::I32(ptr::read(ptr as *const i32)),
                ir::types::I64 => RuntimeValue::I64(ptr::read(ptr as *const i64)),
                ir::types::F32 => RuntimeValue::F32(ptr::read(ptr as *const u32)),
                ir::types::F64 => RuntimeValue::F64(ptr::read(ptr as *const u64)),
                other => panic!("unsupported value type {:?}", other),
            }
        })
        .collect();
    Ok(ActionOutcome::Returned { values })
}
pub fn invoke ( compiler : & mut Compiler , instance : & mut Instance , function_name : & str , args : & [ RuntimeValue ] , ) -> Result < ActionOutcome , ActionError > { let ( address , signature , callee_vmctx ) = match instance . lookup ( function_name ) { Some ( Export :: Function { address , signature , vmctx , } ) => ( address , signature , vmctx ) , Some ( _ ) => { return Err ( ActionError :: Kind ( format ! ( " \" \" " function_name ) ) ) } None => { return Err ( ActionError :: Field ( format ! ( " \" \" " function_name ) ) ) } } ; for ( index , value ) in args . iter ( ) . enumerate ( ) { assert_eq ! ( value value_type ( ) signature params [ index ] value_type ) ; } // TODO: Support values larger than u64. And pack the values into memory // instead of just using fixed-sized slots. let value_size = mem :: size_of :: < u64 > ( ) ; let mut values_vec : Vec < u64 > = vec ! [ 0 max ( signature params len ( ) signature returns len ( ) ) ] ; // Store the argument values into `values_vec`. for ( index , arg ) in args . iter ( ) . enumerate ( ) { unsafe { let ptr = values_vec . as_mut_ptr ( ) . add ( index ) ; match arg { RuntimeValue :: I32 ( x ) => ptr :: write ( ptr as * mut i32 , * x ) , RuntimeValue :: I64 ( x ) => ptr :: write ( ptr as * mut i64 , * x ) , RuntimeValue :: F32 ( x ) => ptr :: write ( ptr as * mut u32 , * x ) , RuntimeValue :: F64 ( x ) => ptr :: write ( ptr as * mut u64 , * x ) , } } } // Get the trampoline to call for this function. let exec_code_buf = compiler . get_trampoline ( address , & signature , value_size ) . map_err ( ActionError :: Setup ) ? ; // Make all JIT code produced thus far executable. compiler . publish_compiled_code ( ) ; // Call the trampoline. if let Err ( message ) = unsafe { wasmtime_call_trampoline ( exec_code_buf , values_vec . as_mut_ptr ( ) as * mut u8 , callee_vmctx , ) } { return Ok ( ActionOutcome :: Trapped { message } ) ; } // Load the return values out of `values_vec`. let values = signature . returns . iter ( ) . enumerate ( ) . map ( | ( index , abi_param ) | unsafe { let ptr = values_vec . as_ptr ( ) . add ( index ) ; match abi_param . value_type { ir :: types :: I32 => RuntimeValue :: I32 ( ptr :: read ( ptr as * const i32 ) ) , ir :: types :: I64 => RuntimeValue :: I64 ( ptr :: read ( ptr as * const i64 ) ) , ir :: types :: F32 => RuntimeValue :: F32 ( ptr :: read ( ptr as * const u32 ) ) , ir :: types :: F64 => RuntimeValue :: F64 ( ptr :: read ( ptr as * const u64 ) ) , other => panic ! ( " " other ) , } } ) . collect ( ) ; Ok ( ActionOutcome :: Returned { values } ) }
Invoke a function in an `Instance` identified by an export name.
Invoke a function in an ` Instance ` identified by an export name .
compiler
&mut Compiler
instance
&mut Instance
function_name
&str
args
&[RuntimeValue]