Split wasmtime-runtime's single getter into typed getters (#3987)

This splits the existing `lookup_by_declaration` function into a
lookup-per-type-of-item. This refactor ends up cleaning up a fair bit of
code in the `wasmtime` crate by removing a number of `unreachable!()`
blocks which are now no longer necessary.
This commit is contained in:
Alex Crichton
2022-03-31 16:24:42 -05:00
committed by GitHub
parent fde84aa79c
commit 353f1b48ab
5 changed files with 91 additions and 87 deletions

View File

@@ -287,55 +287,51 @@ impl Instance {
self.vmctx() as *const VMContext as *mut VMContext self.vmctx() as *const VMContext as *mut VMContext
} }
/// Lookup an export with the given export declaration. fn get_exported_func(&mut self, index: FuncIndex) -> ExportFunction {
pub fn lookup_by_declaration(&mut self, export: &EntityIndex) -> Export { let anyfunc = self.get_caller_checked_anyfunc(index).unwrap();
match export { let anyfunc = NonNull::new(anyfunc as *const VMCallerCheckedAnyfunc as *mut _).unwrap();
EntityIndex::Function(index) => { ExportFunction { anyfunc }
let anyfunc = self.get_caller_checked_anyfunc(*index).unwrap();
let anyfunc =
NonNull::new(anyfunc as *const VMCallerCheckedAnyfunc as *mut _).unwrap();
ExportFunction { anyfunc }.into()
} }
EntityIndex::Table(index) => {
let (definition, vmctx) = fn get_exported_table(&mut self, index: TableIndex) -> ExportTable {
if let Some(def_index) = self.module().defined_table_index(*index) { let (definition, vmctx) = if let Some(def_index) = self.module().defined_table_index(index)
{
(self.table_ptr(def_index), self.vmctx_ptr()) (self.table_ptr(def_index), self.vmctx_ptr())
} else { } else {
let import = self.imported_table(*index); let import = self.imported_table(index);
(import.from, import.vmctx) (import.from, import.vmctx)
}; };
ExportTable { ExportTable {
definition, definition,
vmctx, vmctx,
table: self.module().table_plans[*index].clone(), table: self.module().table_plans[index].clone(),
} }
.into()
} }
EntityIndex::Memory(index) => {
let (definition, vmctx) = fn get_exported_memory(&mut self, index: MemoryIndex) -> ExportMemory {
if let Some(def_index) = self.module().defined_memory_index(*index) { let (definition, vmctx) = if let Some(def_index) = self.module().defined_memory_index(index)
{
(self.memory_ptr(def_index), self.vmctx_ptr()) (self.memory_ptr(def_index), self.vmctx_ptr())
} else { } else {
let import = self.imported_memory(*index); let import = self.imported_memory(index);
(import.from, import.vmctx) (import.from, import.vmctx)
}; };
ExportMemory { ExportMemory {
definition, definition,
vmctx, vmctx,
memory: self.module().memory_plans[*index].clone(), memory: self.module().memory_plans[index].clone(),
} }
.into()
} }
EntityIndex::Global(index) => ExportGlobal {
definition: if let Some(def_index) = self.module().defined_global_index(*index) { fn get_exported_global(&mut self, index: GlobalIndex) -> ExportGlobal {
ExportGlobal {
definition: if let Some(def_index) = self.module().defined_global_index(index) {
self.global_ptr(def_index) self.global_ptr(def_index)
} else { } else {
self.imported_global(*index).from self.imported_global(index).from
}, },
vmctx: self.vmctx_ptr(), vmctx: self.vmctx_ptr(),
global: self.module().globals[*index], global: self.module().globals[index],
}
.into(),
} }
} }
@@ -1062,9 +1058,34 @@ impl InstanceHandle {
self.instance().module() self.instance().module()
} }
/// Lookup an export with the given export declaration. /// Lookup a function by index.
pub fn lookup_by_declaration(&mut self, export: &EntityIndex) -> Export { pub fn get_exported_func(&mut self, export: FuncIndex) -> ExportFunction {
self.instance_mut().lookup_by_declaration(export) self.instance_mut().get_exported_func(export)
}
/// Lookup a global by index.
pub fn get_exported_global(&mut self, export: GlobalIndex) -> ExportGlobal {
self.instance_mut().get_exported_global(export)
}
/// Lookup a memory by index.
pub fn get_exported_memory(&mut self, export: MemoryIndex) -> ExportMemory {
self.instance_mut().get_exported_memory(export)
}
/// Lookup a table by index.
pub fn get_exported_table(&mut self, export: TableIndex) -> ExportTable {
self.instance_mut().get_exported_table(export)
}
/// Lookup an item with the given index.
pub fn get_export_by_index(&mut self, export: EntityIndex) -> Export {
match export {
EntityIndex::Function(i) => Export::Function(self.get_exported_func(i)),
EntityIndex::Global(i) => Export::Global(self.get_exported_global(i)),
EntityIndex::Table(i) => Export::Table(self.get_exported_table(i)),
EntityIndex::Memory(i) => Export::Memory(self.get_exported_memory(i)),
}
} }
/// Return an iterator over the exports of this instance. /// Return an iterator over the exports of this instance.

View File

@@ -10,7 +10,7 @@ use std::panic::{self, AssertUnwindSafe};
use std::pin::Pin; use std::pin::Pin;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::sync::Arc; use std::sync::Arc;
use wasmtime_environ::{EntityIndex, FuncIndex}; use wasmtime_environ::FuncIndex;
use wasmtime_runtime::{ use wasmtime_runtime::{
raise_user_trap, ExportFunction, InstanceAllocator, InstanceHandle, OnDemandInstanceAllocator, raise_user_trap, ExportFunction, InstanceAllocator, InstanceHandle, OnDemandInstanceAllocator,
VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport, VMSharedSignatureIndex, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport, VMSharedSignatureIndex,
@@ -2047,11 +2047,7 @@ impl HostFunc {
/// Requires that this function's signature is already registered within /// Requires that this function's signature is already registered within
/// `Engine`. This happens automatically during the above two constructors. /// `Engine`. This happens automatically during the above two constructors.
fn _new(engine: &Engine, mut instance: InstanceHandle, trampoline: VMTrampoline) -> Self { fn _new(engine: &Engine, mut instance: InstanceHandle, trampoline: VMTrampoline) -> Self {
let idx = EntityIndex::Function(FuncIndex::from_u32(0)); let export = instance.get_exported_func(FuncIndex::from_u32(0));
let export = match instance.lookup_by_declaration(&idx) {
wasmtime_runtime::Export::Function(f) => f,
_ => unreachable!(),
};
HostFunc { HostFunc {
instance, instance,

View File

@@ -8,9 +8,7 @@ use crate::{
use anyhow::{anyhow, bail, Context, Error, Result}; use anyhow::{anyhow, bail, Context, Error, Result};
use std::mem; use std::mem;
use std::sync::Arc; use std::sync::Arc;
use wasmtime_environ::{ use wasmtime_environ::{EntityType, FuncIndex, GlobalIndex, MemoryIndex, PrimaryMap, TableIndex};
EntityIndex, EntityType, FuncIndex, GlobalIndex, MemoryIndex, PrimaryMap, TableIndex,
};
use wasmtime_runtime::{ use wasmtime_runtime::{
Imports, InstanceAllocationRequest, InstantiationError, StorePtr, VMContext, VMFunctionBody, Imports, InstanceAllocationRequest, InstantiationError, StorePtr, VMContext, VMFunctionBody,
VMFunctionImport, VMGlobalImport, VMMemoryImport, VMTableImport, VMFunctionImport, VMGlobalImport, VMMemoryImport, VMTableImport,
@@ -237,7 +235,7 @@ impl Instance {
let id = data.id; let id = data.id;
let instance = store.instance_mut(id); // reborrow the &mut Instancehandle let instance = store.instance_mut(id); // reborrow the &mut Instancehandle
let item = let item =
unsafe { Extern::from_wasmtime_export(instance.lookup_by_declaration(&index), store) }; unsafe { Extern::from_wasmtime_export(instance.get_export_by_index(index), store) };
let data = &mut store[self.0]; let data = &mut store[self.0];
data.exports[i] = Some(item.clone()); data.exports[i] = Some(item.clone());
Some(item) Some(item)
@@ -532,10 +530,7 @@ impl<'a> Instantiator<'a> {
// If a start function is present, invoke it. Make sure we use all the // If a start function is present, invoke it. Make sure we use all the
// trap-handling configuration in `store` as well. // trap-handling configuration in `store` as well.
let instance = store.0.instance_mut(id); let instance = store.0.instance_mut(id);
let f = match instance.lookup_by_declaration(&EntityIndex::Function(start)) { let f = instance.get_exported_func(start);
wasmtime_runtime::Export::Function(f) => f,
_ => unreachable!(), // valid modules shouldn't hit this
};
let vmctx = instance.vmctx_ptr(); let vmctx = instance.vmctx_ptr();
unsafe { unsafe {
super::func::invoke_wasm_and_catch_traps(store, |_default_callee| { super::func::invoke_wasm_and_catch_traps(store, |_default_callee| {

View File

@@ -17,7 +17,7 @@ use crate::{GlobalType, MemoryType, TableType, Val};
use anyhow::Result; use anyhow::Result;
use std::any::Any; use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
use wasmtime_environ::{EntityIndex, GlobalIndex, MemoryIndex, Module, SignatureIndex, TableIndex}; use wasmtime_environ::{GlobalIndex, MemoryIndex, Module, SignatureIndex, TableIndex};
use wasmtime_runtime::{ use wasmtime_runtime::{
Imports, InstanceAllocationRequest, InstanceAllocator, OnDemandInstanceAllocator, StorePtr, Imports, InstanceAllocationRequest, InstanceAllocator, OnDemandInstanceAllocator, StorePtr,
VMFunctionImport, VMSharedSignatureIndex, VMFunctionImport, VMSharedSignatureIndex,
@@ -60,11 +60,9 @@ pub fn generate_global_export(
val: Val, val: Val,
) -> Result<wasmtime_runtime::ExportGlobal> { ) -> Result<wasmtime_runtime::ExportGlobal> {
let instance = create_global(store, gt, val)?; let instance = create_global(store, gt, val)?;
let idx = EntityIndex::Global(GlobalIndex::from_u32(0)); Ok(store
match store.instance_mut(instance).lookup_by_declaration(&idx) { .instance_mut(instance)
wasmtime_runtime::Export::Global(g) => Ok(g), .get_exported_global(GlobalIndex::from_u32(0)))
_ => unreachable!(),
}
} }
pub fn generate_memory_export( pub fn generate_memory_export(
@@ -72,11 +70,9 @@ pub fn generate_memory_export(
m: &MemoryType, m: &MemoryType,
) -> Result<wasmtime_runtime::ExportMemory> { ) -> Result<wasmtime_runtime::ExportMemory> {
let instance = create_memory(store, m)?; let instance = create_memory(store, m)?;
let idx = EntityIndex::Memory(MemoryIndex::from_u32(0)); Ok(store
match store.instance_mut(instance).lookup_by_declaration(&idx) { .instance_mut(instance)
wasmtime_runtime::Export::Memory(m) => Ok(m), .get_exported_memory(MemoryIndex::from_u32(0)))
_ => unreachable!(),
}
} }
pub fn generate_table_export( pub fn generate_table_export(
@@ -84,9 +80,7 @@ pub fn generate_table_export(
t: &TableType, t: &TableType,
) -> Result<wasmtime_runtime::ExportTable> { ) -> Result<wasmtime_runtime::ExportTable> {
let instance = create_table(store, t)?; let instance = create_table(store, t)?;
let idx = EntityIndex::Table(TableIndex::from_u32(0)); Ok(store
match store.instance_mut(instance).lookup_by_declaration(&idx) { .instance_mut(instance)
wasmtime_runtime::Export::Table(t) => Ok(t), .get_exported_table(TableIndex::from_u32(0)))
_ => unreachable!(),
}
} }

View File

@@ -71,11 +71,9 @@ pub fn create_global(store: &mut StoreOpaque, gt: &GlobalType, val: Val) -> Resu
if let Some(x) = externref_init { if let Some(x) = externref_init {
let instance = store.instance_mut(id); let instance = store.instance_mut(id);
match instance.lookup_by_declaration(&EntityIndex::Global(global_id)) { let g = instance.get_exported_global(global_id);
wasmtime_runtime::Export::Global(g) => unsafe { unsafe {
*(*g.definition).as_externref_mut() = Some(x.inner); *(*g.definition).as_externref_mut() = Some(x.inner);
},
_ => unreachable!(),
} }
} }