Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wizer/src/component/snapshot.rs
3072 views
1
use wasmparser::ValType;
2
3
use crate::component::info::Accessor;
4
use crate::component::{ComponentContext, ComponentInstanceState, WIZER_INSTANCE};
5
use crate::snapshot::Snapshot;
6
use crate::{InstanceState, SnapshotVal};
7
8
/// Snapshot result of a component.
9
///
10
/// Currently this only contains the state for instances found within the
11
/// component, and each instance's snapshot is defined as the same core wasm
12
/// snapshot state.
13
pub struct ComponentSnapshot {
14
/// List of snapshots for corresponding module indices.
15
///
16
/// Note that modules don't get a snapshot if they aren't instantiated.
17
pub(crate) modules: Vec<(u32, Snapshot)>,
18
}
19
20
pub async fn snapshot(
21
component: &ComponentContext<'_>,
22
ctx: &mut impl ComponentInstanceState,
23
) -> ComponentSnapshot {
24
let mut modules = Vec::new();
25
26
for (module_index, module) in component.core_modules() {
27
// Ignore uninstantiated modules.
28
if !component.core_instantiations.contains_key(&module_index) {
29
continue;
30
}
31
32
// Use the core-level snapshotting routines to collect a
33
// snapshot of the module. Requests for core-level items are
34
// redirected through the component-level `ctx` provided.
35
let snapshot = crate::snapshot::snapshot(
36
module,
37
&mut ViaComponent {
38
ctx,
39
module_index,
40
component,
41
},
42
)
43
.await;
44
modules.push((module_index, snapshot));
45
}
46
47
ComponentSnapshot { modules }
48
}
49
50
/// Implementation of `InstanceState` via component model primitives.
51
struct ViaComponent<'a, 'b, S> {
52
ctx: &'a mut S,
53
component: &'a ComponentContext<'b>,
54
module_index: u32,
55
}
56
57
impl<'a, S> ViaComponent<'a, '_, S>
58
where
59
S: ComponentInstanceState,
60
{
61
fn get_accessor(&self, name: &str) -> &'a Accessor {
62
let accessors = self.component.accessors.as_ref().unwrap();
63
accessors
64
.iter()
65
.find(|a| match a {
66
Accessor::Global {
67
module_index,
68
core_export_name,
69
..
70
}
71
| Accessor::Memory {
72
module_index,
73
core_export_name,
74
..
75
} => *module_index == self.module_index && core_export_name == name,
76
})
77
.unwrap()
78
}
79
}
80
81
impl<S> InstanceState for ViaComponent<'_, '_, S>
82
where
83
S: ComponentInstanceState,
84
{
85
async fn global_get(&mut self, name: &str, _: ValType) -> SnapshotVal {
86
let Accessor::Global {
87
accessor_export_name,
88
ty,
89
..
90
} = self.get_accessor(name)
91
else {
92
panic!("expected global accessor for {name}");
93
};
94
match ty {
95
wasmparser::ValType::I32 => SnapshotVal::I32(
96
self.ctx
97
.call_func_ret_s32(WIZER_INSTANCE, accessor_export_name)
98
.await,
99
),
100
wasmparser::ValType::I64 => SnapshotVal::I64(
101
self.ctx
102
.call_func_ret_s64(WIZER_INSTANCE, accessor_export_name)
103
.await,
104
),
105
wasmparser::ValType::F32 => SnapshotVal::F32(
106
self.ctx
107
.call_func_ret_f32(WIZER_INSTANCE, accessor_export_name)
108
.await,
109
),
110
wasmparser::ValType::F64 => SnapshotVal::F64(
111
self.ctx
112
.call_func_ret_f64(WIZER_INSTANCE, accessor_export_name)
113
.await,
114
),
115
wasmparser::ValType::V128 => todo!(),
116
wasmparser::ValType::Ref(_) => unreachable!(),
117
}
118
}
119
120
async fn memory_contents(&mut self, name: &str, contents: impl FnOnce(&[u8]) + Send) {
121
let Accessor::Memory {
122
accessor_export_name,
123
..
124
} = self.get_accessor(name)
125
else {
126
panic!("expected memory accessor for {name}");
127
};
128
self.ctx
129
.call_func_ret_list_u8(WIZER_INSTANCE, accessor_export_name, contents)
130
.await
131
}
132
}
133
134