Skip to content

Commit

Permalink
Try #2511:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Aug 10, 2021
2 parents de00f7e + b91b2c2 commit 93c80cf
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 193 deletions.
438 changes: 246 additions & 192 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion lib/api/src/sys/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,13 +522,26 @@ impl Function {
/// assert_eq!(sum.call(&[Value::I32(1), Value::I32(2)]).unwrap().to_vec(), vec![Value::I32(3)]);
/// ```
pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>, RuntimeError> {
// If it's a function defined in the Wasm, it will always have a call_trampoline
if let Some(trampoline) = self.exported.vm_function.call_trampoline {
let mut results = vec![Val::null(); self.result_arity()];
self.call_wasm(trampoline, params, &mut results)?;
return Ok(results.into_boxed_slice());
}

unimplemented!("The function definition isn't supported for the moment");
// If it's a function defined in the host
match self.exported.vm_function.kind {
VMFunctionKind::Dynamic => unsafe {
type VMContextWithEnv = VMDynamicFunctionContext<DynamicFunction<std::ffi::c_void>>;
let ctx = self.exported.vm_function.vmctx.host_env as *mut VMContextWithEnv;
Ok((*ctx).ctx.call(&params)?.into_boxed_slice())
},
VMFunctionKind::Static => {
unimplemented!(
"Native function definitions can't be directly called from the host yet"
);
}
}
}

pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportFunction) -> Self {
Expand Down
25 changes: 25 additions & 0 deletions lib/api/tests/js_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,31 @@ mod js {
assert_eq!(exported.call(&[Val::I32(4)]), Ok(expected));
}

#[wasm_bindgen_test]
fn test_unit_native_function_env() {
let store = Store::default();
#[derive(WasmerEnv, Clone)]
struct Env {
multiplier: u32,
}

fn imported_fn(env: &Env, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
let value = env.multiplier * args[0].unwrap_i32() as u32;
return Ok(vec![Val::I32(value as _)]);
}

let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
let imported = Function::new_with_env(
&store,
imported_signature,
Env { multiplier: 3 },
imported_fn,
);

let expected = vec![Val::I32(12)].into_boxed_slice();
assert_eq!(imported.call(&[Val::I32(4)]), Ok(expected));
}

#[wasm_bindgen_test]
fn test_imported_function_with_wasmer_env() {
let store = Store::default();
Expand Down
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions lib/api/tests/sys/instance.rs → lib/api/tests/sys_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,32 @@ mod sys {

Ok(())
}

#[test]
fn unit_native_function_env() -> Result<()> {
let store = Store::default();
#[derive(WasmerEnv, Clone)]
struct Env {
multiplier: u32,
}

fn imported_fn(env: &Env, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
let value = env.multiplier * args[0].unwrap_i32() as u32;
return Ok(vec![Val::I32(value as _)]);
}

let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
let imported = Function::new_with_env(
&store,
imported_signature,
Env { multiplier: 3 },
imported_fn,
);

let expected = vec![Val::I32(12)].into_boxed_slice();
let result = imported.call(&[Val::I32(4)])?;
assert_eq!(result, expected);

Ok(())
}
}
File renamed without changes.
File renamed without changes.

0 comments on commit 93c80cf

Please sign in to comment.