Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wizer/src/parse.rs
2459 views
1
use crate::info::ModuleContext;
2
use anyhow::{Context, bail};
3
use wasmparser::{Encoding, Parser};
4
5
/// Parse the given Wasm bytes into a `ModuleInfo` tree.
6
pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ModuleContext<'a>> {
7
parse_with(full_wasm, &mut Parser::new(0).parse_all(full_wasm))
8
}
9
10
pub(crate) fn parse_with<'a>(
11
full_wasm: &'a [u8],
12
payloads: &mut impl Iterator<Item = wasmparser::Result<wasmparser::Payload<'a>>>,
13
) -> anyhow::Result<ModuleContext<'a>> {
14
log::debug!("Parsing the input Wasm");
15
16
let mut module = ModuleContext::default();
17
18
while let Some(payload) = payloads.next() {
19
use wasmparser::Payload::*;
20
21
let payload = payload.context("failed to parse Wasm")?;
22
23
if let Some((id, range)) = payload.as_section() {
24
module.add_raw_section(id, range, full_wasm);
25
}
26
27
match payload {
28
Version {
29
encoding: Encoding::Component,
30
..
31
} => {
32
bail!("expected a core module, found a component");
33
}
34
ImportSection(imports) => import_section(&mut module, imports)?,
35
FunctionSection(funcs) => function_section(&mut module, funcs)?,
36
TableSection(tables) => table_section(&mut module, tables)?,
37
MemorySection(mems) => memory_section(&mut module, mems)?,
38
GlobalSection(globals) => global_section(&mut module, globals)?,
39
ExportSection(exports) => export_section(&mut module, exports)?,
40
End { .. } => break,
41
_ => {}
42
}
43
}
44
45
Ok(module)
46
}
47
48
fn import_section<'a>(
49
module: &mut ModuleContext<'a>,
50
imports: wasmparser::ImportSectionReader<'a>,
51
) -> anyhow::Result<()> {
52
// Check that we can properly handle all imports.
53
for imp in imports {
54
let imp = imp?;
55
56
if imp.module.starts_with("__wizer_") || imp.name.starts_with("__wizer_") {
57
anyhow::bail!(
58
"input Wasm module already imports entities named with the `__wizer_*` prefix"
59
);
60
}
61
62
module.push_import(imp);
63
}
64
Ok(())
65
}
66
67
fn function_section<'a>(
68
module: &mut ModuleContext<'a>,
69
funcs: wasmparser::FunctionSectionReader<'a>,
70
) -> anyhow::Result<()> {
71
for ty_idx in funcs {
72
module.push_function(ty_idx?);
73
}
74
Ok(())
75
}
76
77
fn table_section<'a>(
78
module: &mut ModuleContext<'a>,
79
tables: wasmparser::TableSectionReader<'a>,
80
) -> anyhow::Result<()> {
81
for table in tables {
82
module.push_table(table?.ty);
83
}
84
Ok(())
85
}
86
87
fn memory_section<'a>(
88
module: &mut ModuleContext<'a>,
89
mems: wasmparser::MemorySectionReader<'a>,
90
) -> anyhow::Result<()> {
91
for m in mems {
92
module.push_defined_memory(m?);
93
}
94
Ok(())
95
}
96
97
fn global_section<'a>(
98
module: &mut ModuleContext<'a>,
99
globals: wasmparser::GlobalSectionReader<'a>,
100
) -> anyhow::Result<()> {
101
for g in globals {
102
module.push_defined_global(g?.ty);
103
}
104
Ok(())
105
}
106
107
fn export_section<'a>(
108
module: &mut ModuleContext<'a>,
109
exports: wasmparser::ExportSectionReader<'a>,
110
) -> anyhow::Result<()> {
111
for export in exports {
112
let export = export?;
113
114
if export.name.starts_with("__wizer_") {
115
anyhow::bail!(
116
"input Wasm module already exports entities named with the `__wizer_*` prefix"
117
);
118
}
119
120
match export.kind {
121
wasmparser::ExternalKind::Tag
122
| wasmparser::ExternalKind::Func
123
| wasmparser::ExternalKind::FuncExact
124
| wasmparser::ExternalKind::Table
125
| wasmparser::ExternalKind::Memory
126
| wasmparser::ExternalKind::Global => {
127
module.push_export(export);
128
}
129
}
130
}
131
Ok(())
132
}
133
134