Update support for the module linking proposal
This commit updates the various tooling used by wasmtime which has new updates to the module linking proposal. This is done primarily to sync with WebAssembly/module-linking#26. The main change implemented here is that wasmtime now supports creating instances from a set of values, nott just from instantiating a module. Additionally subtyping handling of modules with respect to imports is now properly handled by desugaring two-level imports to imports of instances. A number of small refactorings are included here as well, but most of them are in accordance with the changes to `wasmparser` and the updated binary format for module linking.
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
use crate::vmcontext::{
|
||||
VMCallerCheckedAnyfunc, VMContext, VMGlobalDefinition, VMMemoryDefinition, VMTableDefinition,
|
||||
};
|
||||
use crate::InstanceHandle;
|
||||
use crate::RuntimeInstance;
|
||||
use std::any::Any;
|
||||
use std::ptr::NonNull;
|
||||
use wasmtime_environ::wasm::Global;
|
||||
use wasmtime_environ::{MemoryPlan, TablePlan};
|
||||
|
||||
/// The value of an export passed from one instance to another.
|
||||
pub enum Export<'a> {
|
||||
pub enum Export {
|
||||
/// A function export value.
|
||||
Function(ExportFunction),
|
||||
|
||||
@@ -22,10 +22,10 @@ pub enum Export<'a> {
|
||||
Global(ExportGlobal),
|
||||
|
||||
/// An instance
|
||||
Instance(&'a InstanceHandle),
|
||||
Instance(RuntimeInstance),
|
||||
|
||||
/// A module
|
||||
Module(&'a dyn Any),
|
||||
Module(Box<dyn Any>),
|
||||
}
|
||||
|
||||
/// A function export value.
|
||||
@@ -38,8 +38,8 @@ pub struct ExportFunction {
|
||||
pub anyfunc: NonNull<VMCallerCheckedAnyfunc>,
|
||||
}
|
||||
|
||||
impl<'a> From<ExportFunction> for Export<'a> {
|
||||
fn from(func: ExportFunction) -> Export<'a> {
|
||||
impl From<ExportFunction> for Export {
|
||||
fn from(func: ExportFunction) -> Export {
|
||||
Export::Function(func)
|
||||
}
|
||||
}
|
||||
@@ -55,8 +55,8 @@ pub struct ExportTable {
|
||||
pub table: TablePlan,
|
||||
}
|
||||
|
||||
impl<'a> From<ExportTable> for Export<'a> {
|
||||
fn from(func: ExportTable) -> Export<'a> {
|
||||
impl From<ExportTable> for Export {
|
||||
fn from(func: ExportTable) -> Export {
|
||||
Export::Table(func)
|
||||
}
|
||||
}
|
||||
@@ -72,8 +72,8 @@ pub struct ExportMemory {
|
||||
pub memory: MemoryPlan,
|
||||
}
|
||||
|
||||
impl<'a> From<ExportMemory> for Export<'a> {
|
||||
fn from(func: ExportMemory) -> Export<'a> {
|
||||
impl From<ExportMemory> for Export {
|
||||
fn from(func: ExportMemory) -> Export {
|
||||
Export::Memory(func)
|
||||
}
|
||||
}
|
||||
@@ -89,8 +89,8 @@ pub struct ExportGlobal {
|
||||
pub global: Global,
|
||||
}
|
||||
|
||||
impl<'a> From<ExportGlobal> for Export<'a> {
|
||||
fn from(func: ExportGlobal) -> Export<'a> {
|
||||
impl From<ExportGlobal> for Export {
|
||||
fn from(func: ExportGlobal) -> Export {
|
||||
Export::Global(func)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use crate::vmcontext::{VMFunctionImport, VMGlobalImport, VMMemoryImport, VMTableImport};
|
||||
use crate::InstanceHandle;
|
||||
use std::any::Any;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::wasm::{InstanceIndex, ModuleIndex};
|
||||
|
||||
/// Resolved import pointers.
|
||||
///
|
||||
@@ -28,15 +24,4 @@ pub struct Imports<'a> {
|
||||
|
||||
/// Resolved addresses for imported globals.
|
||||
pub globals: &'a [VMGlobalImport],
|
||||
|
||||
/// Resolved imported instances.
|
||||
pub instances: PrimaryMap<InstanceIndex, InstanceHandle>,
|
||||
|
||||
/// Resolved imported modules.
|
||||
///
|
||||
/// Note that `Box<Any>` here is chosen to allow the embedder of this crate
|
||||
/// to pick an appropriate representation of what module type should be. For
|
||||
/// example for the `wasmtime` crate it's `wasmtime::Module` but that's not
|
||||
/// defined way down here in this low crate.
|
||||
pub modules: PrimaryMap<ModuleIndex, Box<dyn Any>>,
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::vmcontext::{
|
||||
VMSharedSignatureIndex, VMTableDefinition, VMTableImport,
|
||||
};
|
||||
use crate::{ExportFunction, ExportGlobal, ExportMemory, ExportTable};
|
||||
use indexmap::IndexMap;
|
||||
use memoffset::offset_of;
|
||||
use more_asserts::assert_lt;
|
||||
use std::alloc::{self, Layout};
|
||||
@@ -22,17 +23,22 @@ use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::{mem, ptr, slice};
|
||||
use thiserror::Error;
|
||||
use wasmtime_environ::entity::{packed_option::ReservedValue, BoxedSlice, EntityRef, PrimaryMap};
|
||||
use wasmtime_environ::wasm::{
|
||||
DataIndex, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex,
|
||||
ElemIndex, EntityIndex, FuncIndex, GlobalIndex, GlobalInit, InstanceIndex, MemoryIndex,
|
||||
ModuleIndex, SignatureIndex, TableElementType, TableIndex, WasmType,
|
||||
ElemIndex, EntityIndex, FuncIndex, GlobalIndex, GlobalInit, MemoryIndex, SignatureIndex,
|
||||
TableElementType, TableIndex, WasmType,
|
||||
};
|
||||
use wasmtime_environ::{ir, DataInitializer, Module, ModuleType, TableElements, VMOffsets};
|
||||
|
||||
/// Runtime representation of an instance value, which erases all `Instance`
|
||||
/// information since instances are just a collection of values.
|
||||
pub type RuntimeInstance = Rc<IndexMap<String, Export>>;
|
||||
|
||||
/// A WebAssembly instance.
|
||||
///
|
||||
/// This is repr(C) to ensure that the vmctx field is last.
|
||||
@@ -50,15 +56,6 @@ pub(crate) struct Instance {
|
||||
/// WebAssembly table data.
|
||||
tables: BoxedSlice<DefinedTableIndex, Table>,
|
||||
|
||||
/// Instances our module defined and their handles.
|
||||
instances: PrimaryMap<InstanceIndex, InstanceHandle>,
|
||||
|
||||
/// Modules that are located in our index space.
|
||||
///
|
||||
/// For now these are `Box<Any>` so the caller can define the type of what a
|
||||
/// module looks like.
|
||||
modules: PrimaryMap<ModuleIndex, Box<dyn Any>>,
|
||||
|
||||
/// Passive elements in this instantiation. As `elem.drop`s happen, these
|
||||
/// entries get removed. A missing entry is considered equivalent to an
|
||||
/// empty slice.
|
||||
@@ -266,18 +263,8 @@ impl Instance {
|
||||
self.vmctx() as *const VMContext as *mut VMContext
|
||||
}
|
||||
|
||||
/// Lookup an export with the given name.
|
||||
pub fn lookup(&self, field: &str) -> Option<Export> {
|
||||
let export = if let Some(export) = self.module.exports.get(field) {
|
||||
export.clone()
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
Some(self.lookup_by_declaration(&export))
|
||||
}
|
||||
|
||||
/// Lookup an export with the given export declaration.
|
||||
pub fn lookup_by_declaration(&self, export: &EntityIndex) -> Export<'_> {
|
||||
pub fn lookup_by_declaration(&self, export: &EntityIndex) -> Export {
|
||||
match export {
|
||||
EntityIndex::Function(index) => {
|
||||
let anyfunc = self.get_caller_checked_anyfunc(*index).unwrap();
|
||||
@@ -326,8 +313,9 @@ impl Instance {
|
||||
}
|
||||
.into(),
|
||||
|
||||
EntityIndex::Instance(index) => Export::Instance(&self.instances[*index]),
|
||||
EntityIndex::Module(index) => Export::Module(&*self.modules[*index]),
|
||||
EntityIndex::Instance(_) | EntityIndex::Module(_) => {
|
||||
panic!("can't use this api for modules/instances")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,8 +843,6 @@ impl InstanceHandle {
|
||||
passive_elements: Default::default(),
|
||||
passive_data,
|
||||
host_state,
|
||||
instances: imports.instances,
|
||||
modules: imports.modules,
|
||||
vmctx: VMContext {},
|
||||
};
|
||||
let layout = instance.alloc_layout();
|
||||
@@ -1015,11 +1001,6 @@ impl InstanceHandle {
|
||||
self.instance().module()
|
||||
}
|
||||
|
||||
/// Lookup an export with the given name.
|
||||
pub fn lookup(&self, field: &str) -> Option<Export> {
|
||||
self.instance().lookup(field)
|
||||
}
|
||||
|
||||
/// Lookup an export with the given export declaration.
|
||||
pub fn lookup_by_declaration(&self, export: &EntityIndex) -> Export {
|
||||
self.instance().lookup_by_declaration(export)
|
||||
|
||||
@@ -37,7 +37,7 @@ pub mod libcalls;
|
||||
pub use crate::export::*;
|
||||
pub use crate::externref::*;
|
||||
pub use crate::imports::Imports;
|
||||
pub use crate::instance::{InstanceHandle, InstantiationError, LinkError};
|
||||
pub use crate::instance::{InstanceHandle, InstantiationError, LinkError, RuntimeInstance};
|
||||
pub use crate::jit_int::GdbJitImageRegistration;
|
||||
pub use crate::memory::{RuntimeLinearMemory, RuntimeMemoryCreator};
|
||||
pub use crate::mmap::Mmap;
|
||||
|
||||
Reference in New Issue
Block a user