mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 05:31:32 +00:00
feat(runtime-core) Feed imported functions with vm::Ctx
again.
… and look for the associated `vm::FuncCtx`. This way, we don't break the rule: “all functions receive a vmctx pointer as first argument.”.
This commit is contained in:
@ -691,7 +691,9 @@ impl FuncEnvironment for FunctionEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call IR with `callee` and `call_args` and inserts it at `pos`
|
/// Generates a call IR with `callee` and `call_args` and inserts it at `pos`
|
||||||
/// TODO: add support for imported functions
|
///
|
||||||
|
/// It's about generating code that calls a local or imported function; in
|
||||||
|
/// WebAssembly: `(call $foo)`.
|
||||||
fn translate_call(
|
fn translate_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut pos: FuncCursor,
|
mut pos: FuncCursor,
|
||||||
@ -771,14 +773,23 @@ impl FuncEnvironment for FunctionEnvironment {
|
|||||||
readonly: true,
|
readonly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let imported_func_ctx_vmctx_addr =
|
||||||
|
pos.func.create_global_value(ir::GlobalValueData::Load {
|
||||||
|
base: imported_func_ctx_addr,
|
||||||
|
offset: (0 as i32).into(),
|
||||||
|
global_type: ptr_type,
|
||||||
|
readonly: true,
|
||||||
|
});
|
||||||
|
|
||||||
let imported_func_addr = pos.ins().global_value(ptr_type, imported_func_addr);
|
let imported_func_addr = pos.ins().global_value(ptr_type, imported_func_addr);
|
||||||
let imported_func_ctx_addr =
|
let imported_func_ctx_vmctx_addr = pos
|
||||||
pos.ins().global_value(ptr_type, imported_func_ctx_addr);
|
.ins()
|
||||||
|
.global_value(ptr_type, imported_func_ctx_vmctx_addr);
|
||||||
|
|
||||||
let sig_ref = pos.func.dfg.ext_funcs[callee].signature;
|
let sig_ref = pos.func.dfg.ext_funcs[callee].signature;
|
||||||
|
|
||||||
let mut args = Vec::with_capacity(call_args.len() + 1);
|
let mut args = Vec::with_capacity(call_args.len() + 1);
|
||||||
args.push(imported_func_ctx_addr);
|
args.push(imported_func_ctx_vmctx_addr);
|
||||||
args.extend(call_args.iter().cloned());
|
args.extend(call_args.iter().cloned());
|
||||||
|
|
||||||
Ok(pos
|
Ok(pos
|
||||||
|
@ -502,7 +502,7 @@ macro_rules! impl_traits {
|
|||||||
// able to unwind through this function.
|
// able to unwind through this function.
|
||||||
#[cfg_attr(nightly, unwind(allowed))]
|
#[cfg_attr(nightly, unwind(allowed))]
|
||||||
extern fn wrap<$( $x, )* Rets, Trap, FN>(
|
extern fn wrap<$( $x, )* Rets, Trap, FN>(
|
||||||
func_ctx: &mut vm::FuncCtx $( , $x: <$x as WasmExternType>::Native )*
|
vmctx: &vm::Ctx $( , $x: <$x as WasmExternType>::Native )*
|
||||||
) -> Rets::CStruct
|
) -> Rets::CStruct
|
||||||
where
|
where
|
||||||
$( $x: WasmExternType, )*
|
$( $x: WasmExternType, )*
|
||||||
@ -510,6 +510,25 @@ macro_rules! impl_traits {
|
|||||||
Trap: TrapEarly<Rets>,
|
Trap: TrapEarly<Rets>,
|
||||||
FN: Fn(&mut vm::Ctx, $( $x, )*) -> Trap,
|
FN: Fn(&mut vm::Ctx, $( $x, )*) -> Trap,
|
||||||
{
|
{
|
||||||
|
// Get the pointer to this `wrap` function.
|
||||||
|
let self_pointer = wrap::<$( $x, )* Rets, Trap, FN> as *const vm::Func;
|
||||||
|
|
||||||
|
// Get the collection of imported functions.
|
||||||
|
let vm_imported_functions = unsafe { &(*vmctx.import_backing).vm_functions };
|
||||||
|
|
||||||
|
// Retrieve the `vm::FuncCtx`.
|
||||||
|
let mut func_ctx: NonNull<vm::FuncCtx> = vm_imported_functions
|
||||||
|
.iter()
|
||||||
|
.find_map(|(_, imported_func)| {
|
||||||
|
if imported_func.func == self_pointer {
|
||||||
|
Some(imported_func.func_ctx)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.expect("Import backing is not well-formed, cannot find `func_ctx`.");
|
||||||
|
let func_ctx = unsafe { func_ctx.as_mut() };
|
||||||
|
|
||||||
// Extract `vm::Ctx` from `vm::FuncCtx`. The
|
// Extract `vm::Ctx` from `vm::FuncCtx`. The
|
||||||
// pointer is always non-null.
|
// pointer is always non-null.
|
||||||
let vmctx = unsafe { func_ctx.vmctx.as_mut() };
|
let vmctx = unsafe { func_ctx.vmctx.as_mut() };
|
||||||
@ -598,7 +617,7 @@ macro_rules! impl_traits {
|
|||||||
// able to unwind through this function.
|
// able to unwind through this function.
|
||||||
#[cfg_attr(nightly, unwind(allowed))]
|
#[cfg_attr(nightly, unwind(allowed))]
|
||||||
extern fn wrap<$( $x, )* Rets, Trap, FN>(
|
extern fn wrap<$( $x, )* Rets, Trap, FN>(
|
||||||
func_ctx: &mut vm::FuncCtx $( , $x: <$x as WasmExternType>::Native )*
|
vmctx: &vm::Ctx $( , $x: <$x as WasmExternType>::Native )*
|
||||||
) -> Rets::CStruct
|
) -> Rets::CStruct
|
||||||
where
|
where
|
||||||
$( $x: WasmExternType, )*
|
$( $x: WasmExternType, )*
|
||||||
@ -606,6 +625,25 @@ macro_rules! impl_traits {
|
|||||||
Trap: TrapEarly<Rets>,
|
Trap: TrapEarly<Rets>,
|
||||||
FN: Fn($( $x, )*) -> Trap,
|
FN: Fn($( $x, )*) -> Trap,
|
||||||
{
|
{
|
||||||
|
// Get the pointer to this `wrap` function.
|
||||||
|
let self_pointer = wrap::<$( $x, )* Rets, Trap, FN> as *const vm::Func;
|
||||||
|
|
||||||
|
// Get the collection of imported functions.
|
||||||
|
let vm_imported_functions = unsafe { &(*vmctx.import_backing).vm_functions };
|
||||||
|
|
||||||
|
// Retrieve the `vm::FuncCtx`.
|
||||||
|
let mut func_ctx: NonNull<vm::FuncCtx> = vm_imported_functions
|
||||||
|
.iter()
|
||||||
|
.find_map(|(_, imported_func)| {
|
||||||
|
if imported_func.func == self_pointer {
|
||||||
|
Some(imported_func.func_ctx)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.expect("Import backing is not well-formed, cannot find `func_ctx`.");
|
||||||
|
let func_ctx = unsafe { func_ctx.as_mut() };
|
||||||
|
|
||||||
// Extract `vm::Ctx` from `vm::FuncCtx`. The
|
// Extract `vm::Ctx` from `vm::FuncCtx`. The
|
||||||
// pointer is always non-null.
|
// pointer is always non-null.
|
||||||
let vmctx = unsafe { func_ctx.vmctx.as_mut() };
|
let vmctx = unsafe { func_ctx.vmctx.as_mut() };
|
||||||
|
Reference in New Issue
Block a user