Skip to content

Commit

Permalink
Update the python extension
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Mar 12, 2020
1 parent 9a74402 commit 93ec8e9
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 67 deletions.
21 changes: 6 additions & 15 deletions crates/misc/py/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,16 @@ use pyo3::exceptions::Exception;
use pyo3::prelude::*;
use pyo3::types::{PyAny, PyDict, PyTuple};
use std::rc::Rc;
use wasmtime_interface_types::ModuleData;

// TODO support non-export functions
#[pyclass]
pub struct Function {
pub instance: wasmtime::Instance,
pub export_name: String,
pub args_types: Vec<wasmtime::ValType>,
pub data: Rc<ModuleData>,
pub func: wasmtime::Func,
}

impl Function {
pub fn func(&self) -> wasmtime::Func {
let e = self
.instance
.get_export(&self.export_name)
.expect("named export")
.clone();
e.func().expect("function export").clone()
self.func.clone()
}
}

Expand All @@ -37,11 +28,11 @@ impl Function {
runtime_args.push(pyobj_to_value(py, item)?);
}
let results = self
.data
.invoke_export(&self.instance, self.export_name.as_str(), &runtime_args)
.map_err(crate::err2py)?;
.func
.call(&runtime_args)
.map_err(|e| crate::err2py(e.into()))?;
let mut py_results = Vec::new();
for result in results {
for result in results.into_vec() {
py_results.push(value_to_pyobj(py, result)?);
}
if py_results.len() == 1 {
Expand Down
8 changes: 1 addition & 7 deletions crates/misc/py/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ use crate::function::Function;
use crate::memory::Memory;
use pyo3::prelude::*;
use pyo3::types::PyDict;
use std::rc::Rc;
use wasmtime_interface_types::ModuleData;

#[pyclass]
pub struct Instance {
pub instance: wasmtime::Instance,
pub data: Rc<ModuleData>,
}

#[pymethods]
Expand All @@ -31,10 +28,7 @@ impl Instance {
let f = Py::new(
py,
Function {
instance: self.instance.clone(),
data: self.data.clone(),
export_name: e.name().to_string(),
args_types,
func: self.instance.exports()[i].func().unwrap().clone(),
},
)?;
exports.set_item(e.name().to_string(), f)?;
Expand Down
45 changes: 21 additions & 24 deletions crates/misc/py/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use pyo3::exceptions::Exception;
use pyo3::prelude::*;
use pyo3::types::{PyAny, PyBytes, PyDict, PySet};
use pyo3::wrap_pyfunction;
use std::rc::Rc;
use wasmtime_interface_types::ModuleData;

mod function;
mod instance;
Expand Down Expand Up @@ -84,36 +82,35 @@ pub fn instantiate(

let module = wasmtime::Module::new(&store, wasm_data).map_err(err2py)?;

let data = Rc::new(ModuleData::new(wasm_data).map_err(err2py)?);

// If this module expects to be able to use wasi then go ahead and hook
// that up into the imported crates.
let wasi = if let Some(module_name) = data.find_wasi_module_name() {
let cx = wasmtime_wasi::WasiCtxBuilder::new()
.build()
.map_err(|e| err2py(e.into()))?;
let wasi = wasmtime_wasi::Wasi::new(&store, cx);
Some((module_name, wasi))
} else {
None
};
let cx = wasmtime_wasi::WasiCtxBuilder::new()
.build()
.map_err(|e| err2py(e.into()))?;
let wasi_snapshot_preview1 = wasmtime_wasi::Wasi::new(&store, cx);
let cx = wasmtime_wasi::old::snapshot_0::WasiCtxBuilder::new()
.build()
.map_err(|e| err2py(e.into()))?;
let wasi_snapshot = wasmtime_wasi::old::snapshot_0::Wasi::new(&store, cx);

let mut imports: Vec<wasmtime::Extern> = Vec::new();
for i in module.imports() {
if i.module() == "wasi_snapshot" {
if let Some(func) = wasi_snapshot.get_export(i.name()) {
imports.push(func.clone().into());
continue;
}
}
if i.module() == "wasi_snapshot_preview1" {
if let Some(func) = wasi_snapshot_preview1.get_export(i.name()) {
imports.push(func.clone().into());
continue;
}
}
let module_name = i.module();
if let Some(m) = import_obj.get_item(module_name) {
let e = find_export_in(m, &store, i.name())?;
imports.push(e);
} else if wasi.is_some() && module_name == wasi.as_ref().unwrap().0 {
let e = wasi
.as_ref()
.unwrap()
.1
.get_export(i.name())
.ok_or_else(|| {
PyErr::new::<Exception, _>(format!("wasi export {} is not found", i.name(),))
})?;
imports.push(e.clone().into());
} else {
return Err(PyErr::new::<Exception, _>(format!(
"imported module {} is not found",
Expand All @@ -127,7 +124,7 @@ pub fn instantiate(

let module = Py::new(py, Module { module })?;

let instance = Py::new(py, Instance { instance, data })?;
let instance = Py::new(py, Instance { instance })?;

Py::new(py, InstantiateResultObject { instance, module })
}
Expand Down
34 changes: 14 additions & 20 deletions crates/misc/py/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,30 @@
use pyo3::exceptions::Exception;
use pyo3::prelude::*;
use pyo3::types::PyAny;
use wasmtime_interface_types::Value;
use wasmtime::Val;

pub fn pyobj_to_value(_: Python, p: &PyAny) -> PyResult<Value> {
pub fn pyobj_to_value(_: Python, p: &PyAny) -> PyResult<Val> {
if let Ok(n) = p.extract() {
Ok(Value::I32(n))
Ok(Val::I32(n))
} else if let Ok(n) = p.extract() {
Ok(Value::U32(n))
Ok(Val::I64(n))
} else if let Ok(n) = p.extract() {
Ok(Value::I64(n))
Ok(Val::F64(n))
} else if let Ok(n) = p.extract() {
Ok(Value::U64(n))
} else if let Ok(n) = p.extract() {
Ok(Value::F64(n))
} else if let Ok(n) = p.extract() {
Ok(Value::F32(n))
} else if let Ok(s) = p.extract() {
Ok(Value::String(s))
Ok(Val::F32(n))
} else {
Err(PyErr::new::<Exception, _>("unsupported value type"))
}
}

pub fn value_to_pyobj(py: Python, value: Value) -> PyResult<PyObject> {
pub fn value_to_pyobj(py: Python, value: Val) -> PyResult<PyObject> {
Ok(match value {
Value::I32(i) => i.into_py(py),
Value::U32(i) => i.into_py(py),
Value::I64(i) => i.into_py(py),
Value::U64(i) => i.into_py(py),
Value::F32(i) => i.into_py(py),
Value::F64(i) => i.into_py(py),
Value::String(i) => i.into_py(py),
Val::I32(i) => i.into_py(py),
Val::I64(i) => i.into_py(py),
Val::F32(i) => i.into_py(py),
Val::F64(i) => i.into_py(py),
Val::AnyRef(_) | Val::FuncRef(_) | Val::V128(_) => {
return Err(PyErr::new::<Exception, _>("unsupported value type"))
}
})
}
2 changes: 1 addition & 1 deletion crates/wasi/src/old/snapshot_0.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use wasi_common::old::snapshot_0::hostcalls;
use wasi_common::old::snapshot_0::WasiCtx;
pub use wasi_common::old::snapshot_0::{WasiCtx, WasiCtxBuilder};

// Defines a `struct Wasi` with member fields and appropriate APIs for dealing
// with all the various WASI exports.
Expand Down

0 comments on commit 93ec8e9

Please sign in to comment.