1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use crate::context::Context;
use crate::externals::Extern;
use crate::module::Module;
use crate::runtime::Store;
use failure::Error;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
use wasmtime_jit::{instantiate, Resolver};
use wasmtime_runtime::{Export, InstanceHandle};
struct SimpleResolver {
imports: Vec<(String, String, Rc<RefCell<Extern>>)>,
}
impl Resolver for SimpleResolver {
fn resolve(&mut self, name: &str, field: &str) -> Option<Export> {
self.imports
.iter()
.find(|(n, f, _)| name == n && field == f)
.map(|(_, _, e)| e.borrow_mut().get_wasmtime_export())
}
}
pub fn instantiate_in_context(
data: &[u8],
imports: Vec<(String, String, Rc<RefCell<Extern>>)>,
mut context: Context,
exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
) -> Result<(InstanceHandle, HashSet<Context>), Error> {
let mut contexts = HashSet::new();
let debug_info = context.debug_info();
let mut resolver = SimpleResolver { imports };
let instance = instantiate(
&mut context.compiler(),
data,
&mut resolver,
exports,
debug_info,
)?;
contexts.insert(context);
Ok((instance, contexts))
}
#[derive(Clone)]
pub struct Instance {
instance_handle: InstanceHandle,
contexts: HashSet<Context>,
exports: Box<[Rc<RefCell<Extern>>]>,
}
impl Instance {
pub fn new(
store: Rc<RefCell<Store>>,
module: Rc<RefCell<Module>>,
externs: &[Rc<RefCell<Extern>>],
) -> Result<Instance, Error> {
let context = store.borrow_mut().context().clone();
let exports = store.borrow_mut().global_exports().clone();
let imports = module
.borrow()
.imports()
.iter()
.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 exports = {
let module = module.borrow();
let mut exports = Vec::with_capacity(module.exports().len());
for export in module.exports() {
let name = export.name().to_string();
let export = instance_handle.lookup(&name).expect("export");
exports.push(Rc::new(RefCell::new(Extern::from_wasmtime_export(
store.clone(),
instance_handle.clone(),
export,
))));
}
exports.into_boxed_slice()
};
Ok(Instance {
instance_handle,
contexts,
exports,
})
}
pub fn exports(&self) -> &[Rc<RefCell<Extern>>] {
&self.exports
}
pub fn from_handle(
store: Rc<RefCell<Store>>,
instance_handle: InstanceHandle,
) -> Result<(Instance, HashMap<String, usize>), Error> {
let contexts = HashSet::new();
let mut exports = Vec::new();
let mut export_names_map = HashMap::new();
let mut mutable = instance_handle.clone();
for (name, _) in instance_handle.clone().exports() {
let export = mutable.lookup(name).expect("export");
export_names_map.insert(name.to_owned(), exports.len());
exports.push(Rc::new(RefCell::new(Extern::from_wasmtime_export(
store.clone(),
instance_handle.clone(),
export.clone(),
))));
}
Ok((
Instance {
instance_handle,
contexts,
exports: exports.into_boxed_slice(),
},
export_names_map,
))
}
pub fn handle(&self) -> &InstanceHandle {
&self.instance_handle
}
pub fn get_wasmtime_memory(&self) -> Option<wasmtime_runtime::Export> {
let mut instance_handle = self.instance_handle.clone();
instance_handle.lookup("memory")
}
}