Use embedded API in the wasmtime-rust (#540)
This commit is contained in:
committed by
Alex Crichton
parent
2737c5e8e5
commit
98266498af
@@ -255,7 +255,7 @@ impl Global {
|
||||
} else {
|
||||
panic!("wasmtime export is not memory")
|
||||
};
|
||||
let ty = GlobalType::from_cranelift_global(global.clone());
|
||||
let ty = GlobalType::from_cranelift_global(&global);
|
||||
Global {
|
||||
_store: store.clone(),
|
||||
r#type: ty,
|
||||
@@ -395,7 +395,7 @@ impl Table {
|
||||
} else {
|
||||
panic!("wasmtime export is not table")
|
||||
};
|
||||
let ty = TableType::from_cranelift_table(table.table.clone());
|
||||
let ty = TableType::from_cranelift_table(&table.table);
|
||||
Table {
|
||||
store: store.clone(),
|
||||
r#type: ty,
|
||||
@@ -479,7 +479,7 @@ impl Memory {
|
||||
} else {
|
||||
panic!("wasmtime export is not memory")
|
||||
};
|
||||
let ty = MemoryType::from_cranelift_memory(memory.memory.clone());
|
||||
let ty = MemoryType::from_cranelift_memory(&memory.memory);
|
||||
Memory {
|
||||
_store: store.clone(),
|
||||
r#type: ty,
|
||||
|
||||
@@ -3,9 +3,10 @@ use crate::externals::Extern;
|
||||
use crate::module::Module;
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::runtime::Store;
|
||||
use crate::types::{ExportType, ExternType, Name};
|
||||
use crate::{HashMap, HashSet};
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::{borrow::ToOwned, boxed::Box, rc::Rc, vec::Vec};
|
||||
use alloc::{boxed::Box, rc::Rc, vec::Vec};
|
||||
use anyhow::Result;
|
||||
use core::cell::RefCell;
|
||||
use wasmtime_jit::{instantiate, Resolver};
|
||||
@@ -49,6 +50,8 @@ pub fn instantiate_in_context(
|
||||
pub struct Instance {
|
||||
instance_handle: InstanceHandle,
|
||||
|
||||
module: HostRef<Module>,
|
||||
|
||||
// We need to keep CodeMemory alive.
|
||||
contexts: HashSet<Context>,
|
||||
|
||||
@@ -70,8 +73,12 @@ impl Instance {
|
||||
.zip(externs.iter())
|
||||
.map(|(i, e)| (i.module().to_string(), i.name().to_string(), e.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
let (mut instance_handle, contexts) =
|
||||
instantiate_in_context(module.borrow().binary(), imports, context, exports)?;
|
||||
let (mut instance_handle, contexts) = instantiate_in_context(
|
||||
module.borrow().binary().expect("binary"),
|
||||
imports,
|
||||
context,
|
||||
exports,
|
||||
)?;
|
||||
|
||||
let exports = {
|
||||
let module = module.borrow();
|
||||
@@ -89,6 +96,7 @@ impl Instance {
|
||||
};
|
||||
Ok(Instance {
|
||||
instance_handle,
|
||||
module: module.clone(),
|
||||
contexts,
|
||||
exports,
|
||||
})
|
||||
@@ -98,14 +106,25 @@ impl Instance {
|
||||
&self.exports
|
||||
}
|
||||
|
||||
pub fn find_export_by_name(&self, name: &str) -> Option<&Extern> {
|
||||
let (i, _) = self
|
||||
.module
|
||||
.borrow()
|
||||
.exports()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, e)| e.name().as_str() == name)?;
|
||||
Some(&self.exports()[i])
|
||||
}
|
||||
|
||||
pub fn from_handle(
|
||||
store: &HostRef<Store>,
|
||||
instance_handle: InstanceHandle,
|
||||
) -> Result<(Instance, HashMap<String, usize>)> {
|
||||
) -> Result<Instance> {
|
||||
let contexts = HashSet::new();
|
||||
|
||||
let mut exports = Vec::new();
|
||||
let mut export_names_map = HashMap::new();
|
||||
let mut exports_types = Vec::new();
|
||||
let mut mutable = instance_handle.clone();
|
||||
for (name, _) in instance_handle.clone().exports() {
|
||||
let export = mutable.lookup(name).expect("export");
|
||||
@@ -115,7 +134,8 @@ impl Instance {
|
||||
// imported into this store using the from_handle() method.
|
||||
let _ = store.borrow_mut().register_cranelift_signature(signature);
|
||||
}
|
||||
export_names_map.insert(name.to_owned(), exports.len());
|
||||
let extern_type = ExternType::from_wasmtime_export(&export);
|
||||
exports_types.push(ExportType::new(Name::new(name), extern_type));
|
||||
exports.push(Extern::from_wasmtime_export(
|
||||
store,
|
||||
instance_handle.clone(),
|
||||
@@ -123,14 +143,17 @@ impl Instance {
|
||||
));
|
||||
}
|
||||
|
||||
Ok((
|
||||
Instance {
|
||||
instance_handle,
|
||||
contexts,
|
||||
exports: exports.into_boxed_slice(),
|
||||
},
|
||||
export_names_map,
|
||||
))
|
||||
let module = HostRef::new(Module::from_exports(
|
||||
store,
|
||||
exports_types.into_boxed_slice(),
|
||||
));
|
||||
|
||||
Ok(Instance {
|
||||
instance_handle,
|
||||
module,
|
||||
contexts,
|
||||
exports: exports.into_boxed_slice(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> &InstanceHandle {
|
||||
|
||||
@@ -170,10 +170,16 @@ fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[Ex
|
||||
Ok((imports.into_boxed_slice(), exports.into_boxed_slice()))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum ModuleCodeSource {
|
||||
Binary(Box<[u8]>),
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Module {
|
||||
store: HostRef<Store>,
|
||||
binary: Box<[u8]>,
|
||||
source: ModuleCodeSource,
|
||||
imports: Box<[ImportType]>,
|
||||
exports: Box<[ExportType]>,
|
||||
}
|
||||
@@ -183,13 +189,16 @@ impl Module {
|
||||
let (imports, exports) = read_imports_and_exports(binary)?;
|
||||
Ok(Module {
|
||||
store: store.clone(),
|
||||
binary: binary.into(),
|
||||
source: ModuleCodeSource::Binary(binary.into()),
|
||||
imports,
|
||||
exports,
|
||||
})
|
||||
}
|
||||
pub(crate) fn binary(&self) -> &[u8] {
|
||||
&self.binary
|
||||
pub(crate) fn binary(&self) -> Option<&[u8]> {
|
||||
match &self.source {
|
||||
ModuleCodeSource::Binary(b) => Some(b),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn validate(_store: &Store, binary: &[u8]) -> bool {
|
||||
validate(binary, None).is_ok()
|
||||
@@ -200,4 +209,12 @@ impl Module {
|
||||
pub fn exports(&self) -> &[ExportType] {
|
||||
&self.exports
|
||||
}
|
||||
pub fn from_exports(store: &HostRef<Store>, exports: Box<[ExportType]>) -> Self {
|
||||
Module {
|
||||
store: store.clone(),
|
||||
source: ModuleCodeSource::Unknown,
|
||||
imports: Box::new([]),
|
||||
exports,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::context::{create_compiler, Context};
|
||||
use crate::context::Context;
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::HashMap;
|
||||
use alloc::{boxed::Box, rc::Rc, string::String};
|
||||
use alloc::{rc::Rc, string::String};
|
||||
use core::cell::RefCell;
|
||||
use cranelift_codegen::{ir, settings};
|
||||
use wasmtime_jit::{CompilationStrategy, Features};
|
||||
@@ -81,11 +81,6 @@ impl Engine {
|
||||
pub(crate) fn config(&self) -> &Config {
|
||||
&self.config
|
||||
}
|
||||
|
||||
pub fn create_wasmtime_context(&self) -> wasmtime_jit::Context {
|
||||
let flags = self.config.flags().clone();
|
||||
wasmtime_jit::Context::new(Box::new(create_compiler(flags, self.config.strategy())))
|
||||
}
|
||||
}
|
||||
|
||||
// Store
|
||||
|
||||
@@ -127,6 +127,22 @@ impl ExternType {
|
||||
_ => panic!("ExternType::ExternMemory expected"),
|
||||
}
|
||||
}
|
||||
pub(crate) fn from_wasmtime_export(export: &wasmtime_runtime::Export) -> Self {
|
||||
match export {
|
||||
wasmtime_runtime::Export::Function { signature, .. } => {
|
||||
ExternType::ExternFunc(FuncType::from_cranelift_signature(signature.clone()))
|
||||
}
|
||||
wasmtime_runtime::Export::Memory { memory, .. } => {
|
||||
ExternType::ExternMemory(MemoryType::from_cranelift_memory(&memory.memory))
|
||||
}
|
||||
wasmtime_runtime::Export::Global { global, .. } => {
|
||||
ExternType::ExternGlobal(GlobalType::from_cranelift_global(&global))
|
||||
}
|
||||
wasmtime_runtime::Export::Table { table, .. } => {
|
||||
ExternType::ExternTable(TableType::from_cranelift_table(&table.table))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function Types
|
||||
@@ -224,7 +240,7 @@ impl GlobalType {
|
||||
self.mutability
|
||||
}
|
||||
|
||||
pub(crate) fn from_cranelift_global(global: cranelift_wasm::Global) -> GlobalType {
|
||||
pub(crate) fn from_cranelift_global(global: &cranelift_wasm::Global) -> GlobalType {
|
||||
let ty = ValType::from_cranelift_type(global.ty);
|
||||
let mutability = if global.mutability {
|
||||
Mutability::Var
|
||||
@@ -254,7 +270,7 @@ impl TableType {
|
||||
&self.limits
|
||||
}
|
||||
|
||||
pub(crate) fn from_cranelift_table(table: cranelift_wasm::Table) -> TableType {
|
||||
pub(crate) fn from_cranelift_table(table: &cranelift_wasm::Table) -> TableType {
|
||||
assert!(if let cranelift_wasm::TableElementType::Func = table.ty {
|
||||
true
|
||||
} else {
|
||||
@@ -281,7 +297,7 @@ impl MemoryType {
|
||||
&self.limits
|
||||
}
|
||||
|
||||
pub(crate) fn from_cranelift_memory(memory: cranelift_wasm::Memory) -> MemoryType {
|
||||
pub(crate) fn from_cranelift_memory(memory: &cranelift_wasm::Memory) -> MemoryType {
|
||||
MemoryType::new(Limits::new(
|
||||
memory.minimum,
|
||||
memory.maximum.unwrap_or(::core::u32::MAX),
|
||||
@@ -294,6 +310,16 @@ impl MemoryType {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Name(String);
|
||||
|
||||
impl Name {
|
||||
pub fn new(value: &str) -> Self {
|
||||
Name(value.to_owned())
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Name {
|
||||
fn from(s: String) -> Name {
|
||||
Name(s)
|
||||
|
||||
@@ -180,6 +180,34 @@ impl Into<AnyRef> for Val {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeValue> for Val {
|
||||
fn from(rv: RuntimeValue) -> Self {
|
||||
match rv {
|
||||
RuntimeValue::I32(i) => Val::I32(i),
|
||||
RuntimeValue::I64(i) => Val::I64(i),
|
||||
RuntimeValue::F32(u) => Val::F32(u),
|
||||
RuntimeValue::F64(u) => Val::F64(u),
|
||||
x => {
|
||||
panic!("unsupported {:?}", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<RuntimeValue> for Val {
|
||||
fn into(self) -> RuntimeValue {
|
||||
match self {
|
||||
Val::I32(i) => RuntimeValue::I32(i),
|
||||
Val::I64(i) => RuntimeValue::I64(i),
|
||||
Val::F32(u) => RuntimeValue::F32(u),
|
||||
Val::F64(u) => RuntimeValue::F64(u),
|
||||
x => {
|
||||
panic!("unsupported {:?}", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_checked_anyfunc(
|
||||
val: Val,
|
||||
store: &HostRef<Store>,
|
||||
|
||||
Reference in New Issue
Block a user