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