141a695f2SAlex Crichton use crate::info::ModuleContext;
2278656ceSAlex Crichton use wasmparser::{Encoding, Parser};
3*228f448bSNick Fitzgerald use wasmtime::{bail, error::Context as _};
4b01815f2SNick Fitzgerald
5e4b38e80SNick Fitzgerald /// Parse the given Wasm bytes into a `ModuleInfo` tree.
parse<'a>(full_wasm: &'a [u8]) -> wasmtime::Result<ModuleContext<'a>>6*228f448bSNick Fitzgerald pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> wasmtime::Result<ModuleContext<'a>> {
7278656ceSAlex Crichton parse_with(full_wasm, &mut Parser::new(0).parse_all(full_wasm))
8278656ceSAlex Crichton }
9278656ceSAlex Crichton
parse_with<'a>( full_wasm: &'a [u8], payloads: &mut impl Iterator<Item = wasmparser::Result<wasmparser::Payload<'a>>>, ) -> wasmtime::Result<ModuleContext<'a>>10278656ceSAlex Crichton pub(crate) fn parse_with<'a>(
11278656ceSAlex Crichton full_wasm: &'a [u8],
12278656ceSAlex Crichton payloads: &mut impl Iterator<Item = wasmparser::Result<wasmparser::Payload<'a>>>,
13*228f448bSNick Fitzgerald ) -> wasmtime::Result<ModuleContext<'a>> {
14e4b38e80SNick Fitzgerald log::debug!("Parsing the input Wasm");
15e4b38e80SNick Fitzgerald
1641a695f2SAlex Crichton let mut module = ModuleContext::default();
17b01815f2SNick Fitzgerald
18278656ceSAlex Crichton while let Some(payload) = payloads.next() {
19e4b38e80SNick Fitzgerald use wasmparser::Payload::*;
2041a695f2SAlex Crichton
2141a695f2SAlex Crichton let payload = payload.context("failed to parse Wasm")?;
2241a695f2SAlex Crichton
2341a695f2SAlex Crichton if let Some((id, range)) = payload.as_section() {
2441a695f2SAlex Crichton module.add_raw_section(id, range, full_wasm);
2541a695f2SAlex Crichton }
2641a695f2SAlex Crichton
27e4b38e80SNick Fitzgerald match payload {
28278656ceSAlex Crichton Version {
29278656ceSAlex Crichton encoding: Encoding::Component,
30278656ceSAlex Crichton ..
31278656ceSAlex Crichton } => {
32278656ceSAlex Crichton bail!("expected a core module, found a component");
33278656ceSAlex Crichton }
3441a695f2SAlex Crichton ImportSection(imports) => import_section(&mut module, imports)?,
3541a695f2SAlex Crichton FunctionSection(funcs) => function_section(&mut module, funcs)?,
3641a695f2SAlex Crichton TableSection(tables) => table_section(&mut module, tables)?,
3741a695f2SAlex Crichton MemorySection(mems) => memory_section(&mut module, mems)?,
3841a695f2SAlex Crichton GlobalSection(globals) => global_section(&mut module, globals)?,
3941a695f2SAlex Crichton ExportSection(exports) => export_section(&mut module, exports)?,
40278656ceSAlex Crichton End { .. } => break,
4141a695f2SAlex Crichton _ => {}
42e4b38e80SNick Fitzgerald }
43e4b38e80SNick Fitzgerald }
44e4b38e80SNick Fitzgerald
4541a695f2SAlex Crichton Ok(module)
46e4b38e80SNick Fitzgerald }
47e4b38e80SNick Fitzgerald
import_section<'a>( module: &mut ModuleContext<'a>, imports: wasmparser::ImportSectionReader<'a>, ) -> wasmtime::Result<()>48e4b38e80SNick Fitzgerald fn import_section<'a>(
4941a695f2SAlex Crichton module: &mut ModuleContext<'a>,
501995ac49SAlex Crichton imports: wasmparser::ImportSectionReader<'a>,
51*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
52e4b38e80SNick Fitzgerald // Check that we can properly handle all imports.
53e63dd69fSAlex Crichton for imp in imports.into_imports() {
541995ac49SAlex Crichton let imp = imp?;
55e4b38e80SNick Fitzgerald
5605cbefa0SAlex Crichton if imp.module.starts_with("__wizer_") || imp.name.starts_with("__wizer_") {
57*228f448bSNick Fitzgerald wasmtime::bail!(
58e4b38e80SNick Fitzgerald "input Wasm module already imports entities named with the `__wizer_*` prefix"
59e4b38e80SNick Fitzgerald );
60e4b38e80SNick Fitzgerald }
61e4b38e80SNick Fitzgerald
6241a695f2SAlex Crichton module.push_import(imp);
63e4b38e80SNick Fitzgerald }
64e4b38e80SNick Fitzgerald Ok(())
65e4b38e80SNick Fitzgerald }
66e4b38e80SNick Fitzgerald
function_section<'a>( module: &mut ModuleContext<'a>, funcs: wasmparser::FunctionSectionReader<'a>, ) -> wasmtime::Result<()>67e4b38e80SNick Fitzgerald fn function_section<'a>(
6841a695f2SAlex Crichton module: &mut ModuleContext<'a>,
691995ac49SAlex Crichton funcs: wasmparser::FunctionSectionReader<'a>,
70*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
711995ac49SAlex Crichton for ty_idx in funcs {
7241a695f2SAlex Crichton module.push_function(ty_idx?);
73e4b38e80SNick Fitzgerald }
74e4b38e80SNick Fitzgerald Ok(())
75e4b38e80SNick Fitzgerald }
76e4b38e80SNick Fitzgerald
table_section<'a>( module: &mut ModuleContext<'a>, tables: wasmparser::TableSectionReader<'a>, ) -> wasmtime::Result<()>77e4b38e80SNick Fitzgerald fn table_section<'a>(
7841a695f2SAlex Crichton module: &mut ModuleContext<'a>,
791995ac49SAlex Crichton tables: wasmparser::TableSectionReader<'a>,
80*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
811995ac49SAlex Crichton for table in tables {
8241a695f2SAlex Crichton module.push_table(table?.ty);
83e4b38e80SNick Fitzgerald }
84e4b38e80SNick Fitzgerald Ok(())
85e4b38e80SNick Fitzgerald }
86e4b38e80SNick Fitzgerald
memory_section<'a>( module: &mut ModuleContext<'a>, mems: wasmparser::MemorySectionReader<'a>, ) -> wasmtime::Result<()>87e4b38e80SNick Fitzgerald fn memory_section<'a>(
8841a695f2SAlex Crichton module: &mut ModuleContext<'a>,
891995ac49SAlex Crichton mems: wasmparser::MemorySectionReader<'a>,
90*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
911995ac49SAlex Crichton for m in mems {
9241a695f2SAlex Crichton module.push_defined_memory(m?);
93e4b38e80SNick Fitzgerald }
94e4b38e80SNick Fitzgerald Ok(())
95e4b38e80SNick Fitzgerald }
96e4b38e80SNick Fitzgerald
global_section<'a>( module: &mut ModuleContext<'a>, globals: wasmparser::GlobalSectionReader<'a>, ) -> wasmtime::Result<()>97e4b38e80SNick Fitzgerald fn global_section<'a>(
9841a695f2SAlex Crichton module: &mut ModuleContext<'a>,
991995ac49SAlex Crichton globals: wasmparser::GlobalSectionReader<'a>,
100*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
1011995ac49SAlex Crichton for g in globals {
10241a695f2SAlex Crichton module.push_defined_global(g?.ty);
103e4b38e80SNick Fitzgerald }
104e4b38e80SNick Fitzgerald Ok(())
105e4b38e80SNick Fitzgerald }
106e4b38e80SNick Fitzgerald
export_section<'a>( module: &mut ModuleContext<'a>, exports: wasmparser::ExportSectionReader<'a>, ) -> wasmtime::Result<()>107e4b38e80SNick Fitzgerald fn export_section<'a>(
10841a695f2SAlex Crichton module: &mut ModuleContext<'a>,
1091995ac49SAlex Crichton exports: wasmparser::ExportSectionReader<'a>,
110*228f448bSNick Fitzgerald ) -> wasmtime::Result<()> {
1111995ac49SAlex Crichton for export in exports {
1121995ac49SAlex Crichton let export = export?;
113e4b38e80SNick Fitzgerald
11405cbefa0SAlex Crichton if export.name.starts_with("__wizer_") {
115*228f448bSNick Fitzgerald wasmtime::bail!(
116e4b38e80SNick Fitzgerald "input Wasm module already exports entities named with the `__wizer_*` prefix"
117e4b38e80SNick Fitzgerald );
118e4b38e80SNick Fitzgerald }
119e4b38e80SNick Fitzgerald
120e4b38e80SNick Fitzgerald match export.kind {
12141a695f2SAlex Crichton wasmparser::ExternalKind::Tag
12241a695f2SAlex Crichton | wasmparser::ExternalKind::Func
12354826c0eSAlex Crichton | wasmparser::ExternalKind::FuncExact
124e4b38e80SNick Fitzgerald | wasmparser::ExternalKind::Table
125e4b38e80SNick Fitzgerald | wasmparser::ExternalKind::Memory
12605cbefa0SAlex Crichton | wasmparser::ExternalKind::Global => {
12741a695f2SAlex Crichton module.push_export(export);
128e4b38e80SNick Fitzgerald }
129e4b38e80SNick Fitzgerald }
130e4b38e80SNick Fitzgerald }
131e4b38e80SNick Fitzgerald Ok(())
132e4b38e80SNick Fitzgerald }
133