Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor #1524

Merged
merged 24 commits into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6ff9c4c
Compute instance exports on demand.
sunfishcode Apr 15, 2020
725355d
Compute module imports and exports on demand too.
sunfishcode Apr 15, 2020
e058c04
Rename wasmtime_environ::Export to EntityIndex.
sunfishcode Apr 16, 2020
05f7534
Add a utility function for computing an ExternType.
sunfishcode Apr 16, 2020
d1f2996
Add a utility function for looking up a function's signature.
sunfishcode Apr 16, 2020
677ab4e
Add a utility function for computing the ValType of a Global.
sunfishcode Apr 16, 2020
8d5c016
Fix a typo in a comment.
sunfishcode Apr 16, 2020
d9a813c
Simplify module imports and exports.
sunfishcode Apr 16, 2020
73c82b7
Make `Instance::exports` return the export names.
sunfishcode Apr 16, 2020
a7bf93e
Remove `Instance::module`.
sunfishcode Apr 16, 2020
9cf5fb7
Use a InstanceHandle utility function.
sunfishcode Apr 16, 2020
842bd95
Don't consume self in the `Func::get*` methods.
sunfishcode Apr 16, 2020
1148814
Use `ExactSizeIterator` to avoid needing separate `num_*` methods.
sunfishcode Apr 16, 2020
e32dcf5
Rename `Extern::func()` etc. to `into_func()` etc.
sunfishcode Apr 17, 2020
5ddf2b3
Revise examples to avoid using `nth`.
sunfishcode Apr 17, 2020
366e8c4
Add convenience methods to instance for getting specific extern types.
sunfishcode Apr 18, 2020
1811256
Use the convenience functions in more tests and examples.
sunfishcode Apr 18, 2020
ad9414d
Avoid cloning strings for `ImportType` and `ExportType`.
sunfishcode Apr 18, 2020
b2b5e8d
Remove more obviated clone() calls.
sunfishcode Apr 20, 2020
e4b07c5
Simplify `Func`'s closure state.
sunfishcode Apr 20, 2020
b53c7c1
Make wasmtime::Export's fields private.
sunfishcode Apr 20, 2020
8050fea
Fix compilation error.
sunfishcode Apr 20, 2020
8d96fff
Make a lifetime parameter explicit, and use better lifetime names.
sunfishcode Apr 20, 2020
2ce07d0
More lifetime cleanups.
sunfishcode Apr 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cranelift/wasm/src/translation_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub struct ElemIndex(u32);
entity_impl!(ElemIndex);

/// WebAssembly global.
#[derive(Debug, Clone, Copy, Hash)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub struct Global {
/// The type of the value stored in the global.
pub ty: ir::Type,
Expand All @@ -79,7 +79,7 @@ pub struct Global {
}

/// Globals are initialized via the `const` operators or by referring to another import.
#[derive(Debug, Clone, Copy, Hash)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub enum GlobalInit {
/// An `i32.const`.
I32Const(i32),
Expand All @@ -102,7 +102,7 @@ pub enum GlobalInit {
}

/// WebAssembly table.
#[derive(Debug, Clone, Copy, Hash)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub struct Table {
/// The type of data stored in elements of the table.
pub ty: TableElementType,
Expand All @@ -113,7 +113,7 @@ pub struct Table {
}

/// WebAssembly table element. Can be a function or a scalar type.
#[derive(Debug, Clone, Copy, Hash)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub enum TableElementType {
/// A scalar type.
Val(ir::Type),
Expand All @@ -122,7 +122,7 @@ pub enum TableElementType {
}

/// WebAssembly linear memory.
#[derive(Debug, Clone, Copy, Hash)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub struct Memory {
/// The minimum number of pages in the memory.
pub minimum: u32,
Expand Down
149 changes: 106 additions & 43 deletions crates/api/src/externals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl Extern {
/// Returns the underlying `Func`, if this external is a function.
///
/// Returns `None` if this is not a function.
pub fn func(&self) -> Option<&Func> {
pub fn into_func(self) -> Option<Func> {
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
match self {
Extern::Func(func) => Some(func),
_ => None,
Expand All @@ -44,7 +44,7 @@ impl Extern {
/// Returns the underlying `Global`, if this external is a global.
///
/// Returns `None` if this is not a global.
pub fn global(&self) -> Option<&Global> {
pub fn into_global(self) -> Option<Global> {
match self {
Extern::Global(global) => Some(global),
_ => None,
Expand All @@ -54,7 +54,7 @@ impl Extern {
/// Returns the underlying `Table`, if this external is a table.
///
/// Returns `None` if this is not a table.
pub fn table(&self) -> Option<&Table> {
pub fn into_table(self) -> Option<Table> {
match self {
Extern::Table(table) => Some(table),
_ => None,
Expand All @@ -64,7 +64,7 @@ impl Extern {
/// Returns the underlying `Memory`, if this external is a memory.
///
/// Returns `None` if this is not a memory.
pub fn memory(&self) -> Option<&Memory> {
pub fn into_memory(self) -> Option<Memory> {
match self {
Extern::Memory(memory) => Some(memory),
_ => None,
Expand All @@ -74,10 +74,10 @@ impl Extern {
/// Returns the type associated with this `Extern`.
pub fn ty(&self) -> ExternType {
match self {
Extern::Func(ft) => ExternType::Func(ft.ty().clone()),
Extern::Memory(ft) => ExternType::Memory(ft.ty().clone()),
Extern::Table(tt) => ExternType::Table(tt.ty().clone()),
Extern::Global(gt) => ExternType::Global(gt.ty().clone()),
Extern::Func(ft) => ExternType::Func(ft.ty()),
Extern::Memory(ft) => ExternType::Memory(ft.ty()),
Extern::Table(tt) => ExternType::Table(tt.ty()),
Extern::Global(gt) => ExternType::Global(gt.ty()),
}
}

Expand All @@ -91,11 +91,11 @@ impl Extern {
}

pub(crate) fn from_wasmtime_export(
wasmtime_export: wasmtime_runtime::Export,
store: &Store,
instance_handle: InstanceHandle,
export: wasmtime_runtime::Export,
) -> Extern {
match export {
match wasmtime_export {
wasmtime_runtime::Export::Function(f) => {
Extern::Func(Func::from_wasmtime_function(f, store, instance_handle))
}
Expand Down Expand Up @@ -164,7 +164,6 @@ impl From<Table> for Extern {
#[derive(Clone)]
pub struct Global {
store: Store,
ty: GlobalType,
wasmtime_export: wasmtime_runtime::ExportGlobal,
wasmtime_handle: InstanceHandle,
}
Expand All @@ -191,27 +190,44 @@ impl Global {
let (wasmtime_handle, wasmtime_export) = generate_global_export(store, &ty, val)?;
Ok(Global {
store: store.clone(),
ty,
wasmtime_export,
wasmtime_handle,
})
}

/// Returns the underlying type of this `global`.
pub fn ty(&self) -> &GlobalType {
&self.ty
pub fn ty(&self) -> GlobalType {
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
// The original export is coming from wasmtime_runtime itself we should
// support all the types coming out of it, so assert such here.
GlobalType::from_wasmtime_global(&self.wasmtime_export.global)
.expect("core wasm global type should be supported")
}

/// Returns the value type of this `global`.
pub fn val_type(&self) -> ValType {
ValType::from_wasmtime_type(self.wasmtime_export.global.ty)
.expect("core wasm type should be supported")
}

/// Returns the underlying mutability of this `global`.
pub fn mutability(&self) -> Mutability {
if self.wasmtime_export.global.mutability {
Mutability::Var
} else {
Mutability::Const
}
}

/// Returns the current [`Val`] of this global.
pub fn get(&self) -> Val {
unsafe {
let definition = &mut *self.wasmtime_export.definition;
match self.ty().content() {
match self.val_type() {
ValType::I32 => Val::from(*definition.as_i32()),
ValType::I64 => Val::from(*definition.as_i64()),
ValType::F32 => Val::F32(*definition.as_u32()),
ValType::F64 => Val::F64(*definition.as_u64()),
_ => unimplemented!("Global::get for {:?}", self.ty().content()),
ty => unimplemented!("Global::get for {:?}", ty),
}
}
}
Expand All @@ -223,15 +239,12 @@ impl Global {
/// Returns an error if this global has a different type than `Val`, or if
/// it's not a mutable global.
pub fn set(&self, val: Val) -> Result<()> {
if self.ty().mutability() != Mutability::Var {
if self.mutability() != Mutability::Var {
bail!("immutable global cannot be set");
}
if val.ty() != *self.ty().content() {
bail!(
"global of type {:?} cannot be set to {:?}",
self.ty().content(),
val.ty()
);
let ty = self.val_type();
if val.ty() != ty {
bail!("global of type {:?} cannot be set to {:?}", ty, val.ty());
}
if !val.comes_from_same_store(&self.store) {
bail!("cross-`Store` values are not supported");
Expand All @@ -254,13 +267,8 @@ impl Global {
store: &Store,
wasmtime_handle: InstanceHandle,
) -> Global {
// The original export is coming from wasmtime_runtime itself we should
// support all the types coming out of it, so assert such here.
let ty = GlobalType::from_wasmtime_global(&wasmtime_export.global)
.expect("core wasm global type should be supported");
Global {
store: store.clone(),
ty: ty,
wasmtime_export,
wasmtime_handle,
}
Expand All @@ -285,7 +293,6 @@ impl Global {
#[derive(Clone)]
pub struct Table {
store: Store,
ty: TableType,
wasmtime_handle: InstanceHandle,
wasmtime_export: wasmtime_runtime::ExportTable,
}
Expand Down Expand Up @@ -326,16 +333,15 @@ impl Table {

Ok(Table {
store: store.clone(),
ty,
wasmtime_handle,
wasmtime_export,
})
}

/// Returns the underlying type of this table, including its element type as
/// well as the maximum/minimum lower bounds.
pub fn ty(&self) -> &TableType {
&self.ty
pub fn ty(&self) -> TableType {
TableType::from_wasmtime_table(&self.wasmtime_export.table.table)
}

fn wasmtime_table_index(&self) -> wasm::DefinedTableIndex {
Expand Down Expand Up @@ -368,7 +374,7 @@ impl Table {

/// Returns the current size of this table.
pub fn size(&self) -> u32 {
unsafe { (&*self.wasmtime_export.definition).current_elements }
unsafe { (*self.wasmtime_export.definition).current_elements }
}

/// Grows the size of this table by `delta` more elements, initialization
Expand Down Expand Up @@ -432,10 +438,8 @@ impl Table {
store: &Store,
wasmtime_handle: wasmtime_runtime::InstanceHandle,
) -> Table {
let ty = TableType::from_wasmtime_table(&wasmtime_export.table.table);
Table {
store: store.clone(),
ty,
wasmtime_handle,
wasmtime_export,
}
Expand Down Expand Up @@ -651,7 +655,6 @@ impl Table {
#[derive(Clone)]
pub struct Memory {
store: Store,
ty: MemoryType,
wasmtime_handle: InstanceHandle,
wasmtime_export: wasmtime_runtime::ExportMemory,
}
Expand Down Expand Up @@ -684,7 +687,6 @@ impl Memory {
generate_memory_export(store, &ty).expect("generated memory");
Memory {
store: store.clone(),
ty,
wasmtime_handle,
wasmtime_export,
}
Expand All @@ -700,14 +702,14 @@ impl Memory {
/// let store = Store::default();
/// let module = Module::new(&store, "(module (memory (export \"mem\") 1))")?;
/// let instance = Instance::new(&module, &[])?;
/// let memory = instance.get_export("mem").unwrap().memory().unwrap();
/// let memory = instance.get_memory("mem").unwrap();
/// let ty = memory.ty();
/// assert_eq!(ty.limits().min(), 1);
/// # Ok(())
/// # }
/// ```
pub fn ty(&self) -> &MemoryType {
&self.ty
pub fn ty(&self) -> MemoryType {
MemoryType::from_wasmtime_memory(&self.wasmtime_export.memory.memory)
}

/// Returns this memory as a slice view that can be read natively in Rust.
Expand Down Expand Up @@ -812,7 +814,7 @@ impl Memory {
/// let store = Store::default();
/// let module = Module::new(&store, "(module (memory (export \"mem\") 1 2))")?;
/// let instance = Instance::new(&module, &[])?;
/// let memory = instance.get_export("mem").unwrap().memory().unwrap();
/// let memory = instance.get_memory("mem").unwrap();
///
/// assert_eq!(memory.size(), 1);
/// assert_eq!(memory.grow(1)?, 1);
Expand All @@ -838,10 +840,8 @@ impl Memory {
store: &Store,
wasmtime_handle: wasmtime_runtime::InstanceHandle,
) -> Memory {
let ty = MemoryType::from_wasmtime_memory(&wasmtime_export.memory.memory);
Memory {
store: store.clone(),
ty: ty,
wasmtime_handle,
wasmtime_export,
}
Expand Down Expand Up @@ -890,3 +890,66 @@ pub unsafe trait MemoryCreator: Send + Sync {
/// Create new LinearMemory
fn new_memory(&self, ty: MemoryType) -> Result<Box<dyn LinearMemory>, String>;
}

// Exports

/// An exported WebAssembly value.
///
/// This type is primarily accessed from the
/// [`Instance::exports`](crate::Instance::exports) accessor and describes what
/// names and items are exported from a wasm instance.
#[derive(Clone)]
pub struct Export<'instance> {
alexcrichton marked this conversation as resolved.
Show resolved Hide resolved
/// The name of the export.
name: &'instance str,

/// The definition of the export.
definition: Extern,
}

impl<'instance> Export<'instance> {
/// Creates a new export which is exported with the given `name` and has the
/// given `definition`.
pub(crate) fn new(name: &'instance str, definition: Extern) -> Export<'instance> {
Export { name, definition }
}

/// Returns the name by which this export is known.
pub fn name(&self) -> &'instance str {
self.name
}

/// Return the `ExternType` of this export.
pub fn ty(&self) -> ExternType {
self.definition.ty()
}

/// Consume this `Export` and return the contained `Extern`.
pub fn into_extern(self) -> Extern {
self.definition
}

/// Consume this `Export` and return the contained `Func`, if it's a function,
/// or `None` otherwise.
pub fn into_func(self) -> Option<Func> {
self.definition.into_func()
}

/// Consume this `Export` and return the contained `Table`, if it's a table,
/// or `None` otherwise.
pub fn into_table(self) -> Option<Table> {
self.definition.into_table()
}

/// Consume this `Export` and return the contained `Memory`, if it's a memory,
/// or `None` otherwise.
pub fn into_memory(self) -> Option<Memory> {
self.definition.into_memory()
}

/// Consume this `Export` and return the contained `Global`, if it's a global,
/// or `None` otherwise.
pub fn into_global(self) -> Option<Global> {
self.definition.into_global()
}
}
Loading