| 
1 | 1 | use crate::prelude::*;  | 
2 | 2 | use crate::runtime::Uninhabited;  | 
3 | 3 | use crate::runtime::vm::{  | 
4 |  | -    InterpreterRef, SendSyncPtr, StoreBox, VMArrayCallHostFuncContext, VMCommonStackInformation,  | 
5 |  | -    VMContext, VMFuncRef, VMFunctionImport, VMOpaqueContext, VMStoreContext,  | 
 | 4 | +    self, InterpreterRef, SendSyncPtr, StoreBox, VMArrayCallHostFuncContext,  | 
 | 5 | +    VMCommonStackInformation, VMContext, VMFuncRef, VMFunctionImport, VMOpaqueContext,  | 
 | 6 | +    VMStoreContext,  | 
6 | 7 | };  | 
7 |  | -use crate::store::{AutoAssertNoGc, StoreId, StoreOpaque};  | 
 | 8 | +use crate::store::{AutoAssertNoGc, InstanceId, StoreId, StoreOpaque};  | 
8 | 9 | use crate::type_registry::RegisteredType;  | 
9 | 10 | use crate::{  | 
10 | 11 |     AsContext, AsContextMut, CallHook, Engine, Extern, FuncType, Instance, ModuleExport, Ref,  | 
@@ -2041,46 +2042,29 @@ impl<T> Caller<'_, T> {  | 
2041 | 2042 | 
 
  | 
2042 | 2043 |     /// Executes `f` with an appropriate `Caller`.  | 
2043 | 2044 |     ///  | 
2044 |  | -    /// This is the entrypoint for host functions in core wasm and converts from  | 
2045 |  | -    /// `VMContext` to `Caller`  | 
2046 |  | -    ///  | 
2047 |  | -    /// # Safety  | 
2048 |  | -    ///  | 
2049 |  | -    /// This requires that `caller` is safe to wrap up as a `Caller`,  | 
2050 |  | -    /// effectively meaning that we just entered the host from wasm.  | 
2051 |  | -    /// Additionally this `Caller`'s `T` parameter must match the actual `T` in  | 
2052 |  | -    /// the store of the vmctx of `caller`.  | 
2053 |  | -    unsafe fn with<F, R>(caller: NonNull<VMContext>, f: F) -> R  | 
 | 2045 | +    /// This is the entrypoint for host functions in core wasm. The `store` and  | 
 | 2046 | +    /// `instance` are created from `Instance::enter_host_from_wasm` and this  | 
 | 2047 | +    /// will further invoke the host function that `f` refers to.  | 
 | 2048 | +    fn with<F, R>(mut store: StoreContextMut<T>, caller: InstanceId, f: F) -> R  | 
2054 | 2049 |     where  | 
2055 | 2050 |         F: FnOnce(Caller<'_, T>) -> R,  | 
2056 | 2051 |     {  | 
2057 |  | -        // SAFETY: it's a contract of this function itself that `from_vmctx` is  | 
2058 |  | -        // safe to call. Additionally it's a contract of this function itself  | 
2059 |  | -        // that the `T` of `Caller` matches the store.  | 
2060 |  | -        unsafe {  | 
2061 |  | -            crate::runtime::vm::InstanceAndStore::from_vmctx(caller, |pair| {  | 
2062 |  | -                let (instance, store) = pair.unpack_mut();  | 
2063 |  | -                let mut store = store.unchecked_context_mut::<T>();  | 
2064 |  | -                let caller = Instance::from_wasmtime(instance.id(), store.0);  | 
 | 2052 | +        let caller = Instance::from_wasmtime(caller, store.0);  | 
2065 | 2053 | 
 
  | 
2066 |  | -                let (gc_lifo_scope, ret) = {  | 
2067 |  | -                    let gc_lifo_scope = store.0.gc_roots().enter_lifo_scope();  | 
 | 2054 | +        let (gc_lifo_scope, ret) = {  | 
 | 2055 | +            let gc_lifo_scope = store.0.gc_roots().enter_lifo_scope();  | 
2068 | 2056 | 
 
  | 
2069 |  | -                    let ret = f(Caller {  | 
2070 |  | -                        store: store.as_context_mut(),  | 
2071 |  | -                        caller,  | 
2072 |  | -                    });  | 
 | 2057 | +            let ret = f(Caller {  | 
 | 2058 | +                store: store.as_context_mut(),  | 
 | 2059 | +                caller,  | 
 | 2060 | +            });  | 
2073 | 2061 | 
 
  | 
2074 |  | -                    (gc_lifo_scope, ret)  | 
2075 |  | -                };  | 
 | 2062 | +            (gc_lifo_scope, ret)  | 
 | 2063 | +        };  | 
2076 | 2064 | 
 
  | 
2077 |  | -                // Safe to recreate a mutable borrow of the store because `ret`  | 
2078 |  | -                // cannot be borrowing from the store.  | 
2079 |  | -                store.0.exit_gc_lifo_scope(gc_lifo_scope);  | 
 | 2065 | +        store.0.exit_gc_lifo_scope(gc_lifo_scope);  | 
2080 | 2066 | 
 
  | 
2081 |  | -                ret  | 
2082 |  | -            })  | 
2083 |  | -        }  | 
 | 2067 | +        ret  | 
2084 | 2068 |     }  | 
2085 | 2069 | 
 
  | 
2086 | 2070 |     fn sub_caller(&mut self) -> Caller<'_, T> {  | 
@@ -2409,10 +2393,14 @@ impl HostContext {  | 
2409 | 2393 |         // closure and then run it as part of `Caller::with`.  | 
2410 | 2394 |         //  | 
2411 | 2395 |         // SAFETY: this is an entrypoint of wasm which requires correct type  | 
2412 |  | -        // ascription of `T` itself, meaning that this should be safe to call.  | 
2413 |  | -        crate::runtime::vm::catch_unwind_and_record_trap(move || unsafe {  | 
2414 |  | -            Caller::with(caller_vmctx, run)  | 
2415 |  | -        })  | 
 | 2396 | +        // ascription of `T` itself, meaning that this should be safe to call  | 
 | 2397 | +        // both `enter_host_from_wasm` as well as `unchecked_context_mut`.  | 
 | 2398 | +        unsafe {  | 
 | 2399 | +            vm::Instance::enter_host_from_wasm(caller_vmctx, |store, instance| {  | 
 | 2400 | +                let store = store.unchecked_context_mut();  | 
 | 2401 | +                Caller::with(store, instance.id(), run)  | 
 | 2402 | +            })  | 
 | 2403 | +        }  | 
2416 | 2404 |     }  | 
2417 | 2405 | }  | 
2418 | 2406 | 
 
  | 
@@ -2485,20 +2473,23 @@ impl HostFunc {  | 
2485 | 2473 |         T: 'static,  | 
2486 | 2474 |     {  | 
2487 | 2475 |         assert!(ty.comes_from_same_engine(engine));  | 
2488 |  | -        // SAFETY: This is only only called in the raw entrypoint of wasm  | 
2489 |  | -        // meaning that `caller_vmctx` is appropriate to read, and additionally  | 
2490 |  | -        // the later usage of `{,in}to_func` will connect `T` to an actual  | 
2491 |  | -        // store's `T` to ensure it's the same.  | 
2492 |  | -        let func = move |caller_vmctx, values: &mut [ValRaw]| unsafe {  | 
2493 |  | -            Caller::<T>::with(caller_vmctx, |mut caller| {  | 
2494 |  | -                caller.store.0.call_hook(CallHook::CallingHost)?;  | 
2495 |  | -                let result = func(caller.sub_caller(), values)?;  | 
2496 |  | -                caller.store.0.call_hook(CallHook::ReturningFromHost)?;  | 
2497 |  | -                Ok(result)  | 
2498 |  | -            })  | 
2499 |  | -        };  | 
2500 |  | -        let ctx = crate::trampoline::create_array_call_function(&ty, func)  | 
2501 |  | -            .expect("failed to create function");  | 
 | 2476 | +        let ctx = crate::trampoline::create_array_call_function(  | 
 | 2477 | +            &ty,  | 
 | 2478 | +            move |store, instance, values: &mut [ValRaw]| {  | 
 | 2479 | +                // SAFETY: the later usage of `{,in}to_func` will connect `T` to  | 
 | 2480 | +                // an actual store's `T` to ensure it's the same. This means  | 
 | 2481 | +                // that the store this is invoked with always has `T` as a type  | 
 | 2482 | +                // parameter which should make this cast safe.  | 
 | 2483 | +                let store = unsafe { store.unchecked_context_mut::<T>() };  | 
 | 2484 | +                Caller::with(store, instance, |mut caller| {  | 
 | 2485 | +                    caller.store.0.call_hook(CallHook::CallingHost)?;  | 
 | 2486 | +                    let result = func(caller.sub_caller(), values)?;  | 
 | 2487 | +                    caller.store.0.call_hook(CallHook::ReturningFromHost)?;  | 
 | 2488 | +                    Ok(result)  | 
 | 2489 | +                })  | 
 | 2490 | +            },  | 
 | 2491 | +        )  | 
 | 2492 | +        .expect("failed to create function");  | 
2502 | 2493 |         HostFunc::_new(engine, ctx.into())  | 
2503 | 2494 |     }  | 
2504 | 2495 | 
 
  | 
 | 
0 commit comments