Optimize codegen in Func::wrap (#1491)
This commit optimizes the codegen of `Func::wrap` such that if you do
something like `Func::wrap(&store, || {})` then the shim generated
contains zero code (as expected). In general this means that the extra
tidbits generated by wasmtime are all eligible to be entirely optimized
away so long as you don't actually rely on something.
This commit is contained in:
@@ -1030,8 +1030,12 @@ macro_rules! impl_into_func {
|
|||||||
R: WasmRet,
|
R: WasmRet,
|
||||||
{
|
{
|
||||||
let ret = {
|
let ret = {
|
||||||
let instance = InstanceHandle::from_vmctx(vmctx);
|
let state = (*vmctx).host_state();
|
||||||
let (func, store) = instance.host_state().downcast_ref::<(F, Store)>().expect("state");
|
// Double-check ourselves in debug mode, but we control
|
||||||
|
// the `Any` here so an unsafe downcast should also
|
||||||
|
// work.
|
||||||
|
debug_assert!(state.is::<(F, Store)>());
|
||||||
|
let (func, store) = &*(state as *const _ as *const (F, Store));
|
||||||
panic::catch_unwind(AssertUnwindSafe(|| {
|
panic::catch_unwind(AssertUnwindSafe(|| {
|
||||||
func(
|
func(
|
||||||
Caller { store, caller_vmctx },
|
Caller { store, caller_vmctx },
|
||||||
|
|||||||
@@ -376,6 +376,7 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return a reference to the custom state attached to this instance.
|
/// Return a reference to the custom state attached to this instance.
|
||||||
|
#[inline]
|
||||||
pub fn host_state(&self) -> &dyn Any {
|
pub fn host_state(&self) -> &dyn Any {
|
||||||
&*self.host_state
|
&*self.host_state
|
||||||
}
|
}
|
||||||
@@ -416,6 +417,7 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the offset from the vmctx pointer to its containing Instance.
|
/// Return the offset from the vmctx pointer to its containing Instance.
|
||||||
|
#[inline]
|
||||||
pub(crate) fn vmctx_offset() -> isize {
|
pub(crate) fn vmctx_offset() -> isize {
|
||||||
offset_of!(Self, vmctx) as isize
|
offset_of!(Self, vmctx) as isize
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -632,6 +632,7 @@ impl VMContext {
|
|||||||
/// This is unsafe because it doesn't work on just any `VMContext`, it must
|
/// This is unsafe because it doesn't work on just any `VMContext`, it must
|
||||||
/// be a `VMContext` allocated as part of an `Instance`.
|
/// be a `VMContext` allocated as part of an `Instance`.
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
#[inline]
|
||||||
pub(crate) unsafe fn instance(&self) -> &Instance {
|
pub(crate) unsafe fn instance(&self) -> &Instance {
|
||||||
&*((self as *const Self as *mut u8).offset(-Instance::vmctx_offset()) as *const Instance)
|
&*((self as *const Self as *mut u8).offset(-Instance::vmctx_offset()) as *const Instance)
|
||||||
}
|
}
|
||||||
@@ -641,6 +642,7 @@ impl VMContext {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// This is unsafe because it doesn't work on just any `VMContext`, it must
|
/// This is unsafe because it doesn't work on just any `VMContext`, it must
|
||||||
/// be a `VMContext` allocated as part of an `Instance`.
|
/// be a `VMContext` allocated as part of an `Instance`.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn host_state(&self) -> &dyn Any {
|
pub unsafe fn host_state(&self) -> &dyn Any {
|
||||||
self.instance().host_state()
|
self.instance().host_state()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user