1mod builder;
2mod custom_section;
3mod data;
4mod element;
5mod export;
6mod global;
7mod import;
8mod init_expr;
9mod instantiate;
10mod parser;
11mod read;
12pub(crate) mod utils;
13
14use self::{
15 builder::ModuleBuilder,
16 custom_section::{CustomSections, CustomSectionsBuilder},
17 export::ExternIdx,
18 global::Global,
19 import::{ExternTypeIdx, Import},
20 parser::ModuleParser,
21};
22pub use self::{
23 custom_section::{CustomSection, CustomSectionsIter},
24 export::{ExportType, FuncIdx, MemoryIdx, ModuleExportsIter, TableIdx},
25 global::GlobalIdx,
26 import::{FuncTypeIdx, ImportName},
27 instantiate::{InstancePre, InstantiationError},
28 read::{Read, ReadError},
29};
30pub(crate) use self::{
31 data::{DataSegment, DataSegments, InitDataSegment, PassiveDataSegmentBytes},
32 element::{ElementSegment, ElementSegmentItems, ElementSegmentKind},
33 init_expr::ConstExpr,
34 utils::WasmiValueType,
35};
36use crate::{
37 collections::Map,
38 engine::{DedupFuncType, EngineFunc, EngineFuncSpan, EngineFuncSpanIter, EngineWeak},
39 Engine,
40 Error,
41 ExternType,
42 FuncType,
43 GlobalType,
44 MemoryType,
45 TableType,
46};
47use core::{iter, slice::Iter as SliceIter};
48use std::{boxed::Box, sync::Arc};
49use wasmparser::{FuncValidatorAllocations, Parser, ValidPayload, Validator};
50
51#[derive(Debug, Clone)]
53pub struct Module {
54 inner: Arc<ModuleInner>,
55}
56
57#[derive(Debug)]
59struct ModuleInner {
60 engine: Engine,
61 header: ModuleHeader,
62 data_segments: DataSegments,
63 custom_sections: CustomSections,
64}
65
66#[derive(Debug, Clone)]
68pub struct ModuleHeader {
69 inner: Arc<ModuleHeaderInner>,
70}
71
72#[derive(Debug)]
73struct ModuleHeaderInner {
74 engine: EngineWeak,
75 func_types: Arc<[DedupFuncType]>,
76 imports: ModuleImports,
77 funcs: Box<[DedupFuncType]>,
78 tables: Box<[TableType]>,
79 memories: Box<[MemoryType]>,
80 globals: Box<[GlobalType]>,
81 globals_init: Box<[ConstExpr]>,
82 exports: Map<Box<str>, ExternIdx>,
83 start: Option<FuncIdx>,
84 engine_funcs: EngineFuncSpan,
85 element_segments: Box<[ElementSegment]>,
86}
87
88impl ModuleHeader {
89 pub fn engine(&self) -> &EngineWeak {
91 &self.inner.engine
92 }
93
94 pub fn get_func_type(&self, func_type_idx: FuncTypeIdx) -> &DedupFuncType {
96 &self.inner.func_types[func_type_idx.into_u32() as usize]
97 }
98
99 pub fn get_type_of_func(&self, func_idx: FuncIdx) -> &DedupFuncType {
101 &self.inner.funcs[func_idx.into_u32() as usize]
102 }
103
104 pub fn get_type_of_global(&self, global_idx: GlobalIdx) -> &GlobalType {
106 &self.inner.globals[global_idx.into_u32() as usize]
107 }
108
109 pub fn get_engine_func(&self, func_idx: FuncIdx) -> Option<EngineFunc> {
113 let index = func_idx.into_u32();
114 let len_imported = self.inner.imports.len_funcs() as u32;
115 let index = index.checked_sub(len_imported)?;
116 Some(self.inner.engine_funcs.get_or_panic(index))
119 }
120
121 pub fn get_func_index(&self, func: EngineFunc) -> Option<FuncIdx> {
123 let position = self.inner.engine_funcs.position(func)?;
124 let len_imports = self.inner.imports.len_funcs as u32;
125 Some(FuncIdx::from(position + len_imports))
126 }
127
128 pub fn get_global(&self, global_idx: GlobalIdx) -> (&GlobalType, Option<&ConstExpr>) {
130 let index = global_idx.into_u32() as usize;
131 let len_imports = self.inner.imports.len_globals();
132 let global_type = self.get_type_of_global(global_idx);
133 if index < len_imports {
134 (global_type, None)
136 } else {
137 let init_expr = &self.inner.globals_init[index - len_imports];
139 (global_type, Some(init_expr))
140 }
141 }
142}
143
144pub(crate) const DEFAULT_MEMORY_INDEX: u32 = 0;
146
147#[derive(Debug)]
149pub enum Imported {
150 Func(ImportName),
154 Table(ImportName),
158 Memory(ImportName),
162 Global(ImportName),
164}
165
166#[derive(Debug)]
168pub struct ModuleImports {
169 items: Box<[Imported]>,
171 len_funcs: usize,
175 len_globals: usize,
177 len_memories: usize,
181 len_tables: usize,
185}
186
187impl ModuleImports {
188 pub fn len_globals(&self) -> usize {
190 self.len_globals
191 }
192
193 pub fn len_funcs(&self) -> usize {
195 self.len_funcs
196 }
197}
198
199impl Module {
200 pub fn new(engine: &Engine, wasm: &[u8]) -> Result<Self, Error> {
215 ModuleParser::new(engine).parse_buffered(wasm)
216 }
217
218 pub fn new_streaming(engine: &Engine, stream: impl Read) -> Result<Self, Error> {
233 ModuleParser::new(engine).parse_streaming(stream)
234 }
235
236 pub unsafe fn new_unchecked(engine: &Engine, wasm: &[u8]) -> Result<Self, Error> {
257 let parser = ModuleParser::new(engine);
258 unsafe { parser.parse_buffered_unchecked(wasm) }
259 }
260
261 pub unsafe fn new_streaming_unchecked(
282 engine: &Engine,
283 stream: impl Read,
284 ) -> Result<Self, Error> {
285 let parser = ModuleParser::new(engine);
286 unsafe { parser.parse_streaming_unchecked(stream) }
287 }
288
289 pub fn engine(&self) -> &Engine {
291 &self.inner.engine
292 }
293
294 fn module_header(&self) -> &ModuleHeaderInner {
296 &self.inner.header.inner
297 }
298
299 pub fn validate(engine: &Engine, wasm: &[u8]) -> Result<(), Error> {
320 let mut validator = Validator::new_with_features(engine.config().wasm_features());
321 for payload in Parser::new(0).parse_all(wasm) {
322 let payload = payload?;
323 if let ValidPayload::Func(func_to_validate, func_body) = validator.payload(&payload)? {
324 func_to_validate
325 .into_validator(FuncValidatorAllocations::default())
326 .validate(&func_body)?;
327 }
328 }
329 Ok(())
330 }
331
332 pub(crate) fn len_funcs(&self) -> usize {
334 self.module_header().funcs.len()
335 }
336 pub(crate) fn len_tables(&self) -> usize {
338 self.module_header().tables.len()
339 }
340 pub(crate) fn len_memories(&self) -> usize {
342 self.module_header().memories.len()
343 }
344 pub(crate) fn len_globals(&self) -> usize {
346 self.module_header().globals.len()
347 }
348
349 pub(crate) fn func_types_cloned(&self) -> Arc<[DedupFuncType]> {
355 self.module_header().func_types.clone()
356 }
357
358 pub fn imports(&self) -> ModuleImportsIter {
360 let header = self.module_header();
361 let len_imported_funcs = header.imports.len_funcs;
362 let len_imported_globals = header.imports.len_globals;
363 ModuleImportsIter {
364 engine: self.engine(),
365 names: header.imports.items.iter(),
366 funcs: header.funcs[..len_imported_funcs].iter(),
367 tables: header.tables.iter(),
368 memories: header.memories.iter(),
369 globals: header.globals[..len_imported_globals].iter(),
370 }
371 }
372
373 pub(crate) fn internal_funcs(&self) -> InternalFuncsIter {
377 let header = self.module_header();
378 let len_imported = header.imports.len_funcs;
379 let funcs = &header.funcs[len_imported..];
383 let engine_funcs = header.engine_funcs.iter();
384 assert_eq!(funcs.len(), engine_funcs.len());
385 InternalFuncsIter {
386 iter: funcs.iter().zip(engine_funcs),
387 }
388 }
389
390 fn internal_memories(&self) -> SliceIter<MemoryType> {
392 let header = self.module_header();
393 let len_imported = header.imports.len_memories;
394 let memories = &header.memories[len_imported..];
398 memories.iter()
399 }
400
401 fn internal_tables(&self) -> SliceIter<TableType> {
403 let header = self.module_header();
404 let len_imported = header.imports.len_tables;
405 let tables = &header.tables[len_imported..];
409 tables.iter()
410 }
411
412 fn internal_globals(&self) -> InternalGlobalsIter {
414 let header = self.module_header();
415 let len_imported = header.imports.len_globals;
416 let globals = header.globals[len_imported..].iter();
420 let global_inits = header.globals_init.iter();
421 InternalGlobalsIter {
422 iter: globals.zip(global_inits),
423 }
424 }
425
426 pub fn exports(&self) -> ModuleExportsIter {
428 ModuleExportsIter::new(self)
429 }
430
431 pub fn get_export(&self, name: &str) -> Option<ExternType> {
439 let idx = self.module_header().exports.get(name).copied()?;
440 let ty = self.get_extern_type(idx);
441 Some(ty)
442 }
443
444 fn get_extern_type(&self, idx: ExternIdx) -> ExternType {
450 let header = self.module_header();
451 match idx {
452 ExternIdx::Func(index) => {
453 let dedup = &header.funcs[index.into_u32() as usize];
454 let func_type = self.engine().resolve_func_type(dedup, Clone::clone);
455 ExternType::Func(func_type)
456 }
457 ExternIdx::Table(index) => {
458 let table_type = header.tables[index.into_u32() as usize];
459 ExternType::Table(table_type)
460 }
461 ExternIdx::Memory(index) => {
462 let memory_type = header.memories[index.into_u32() as usize];
463 ExternType::Memory(memory_type)
464 }
465 ExternIdx::Global(index) => {
466 let global_type = header.globals[index.into_u32() as usize];
467 ExternType::Global(global_type)
468 }
469 }
470 }
471
472 #[inline]
482 pub fn custom_sections(&self) -> CustomSectionsIter {
483 self.inner.custom_sections.iter()
484 }
485}
486
487#[derive(Debug)]
489pub struct ModuleImportsIter<'a> {
490 engine: &'a Engine,
491 names: SliceIter<'a, Imported>,
492 funcs: SliceIter<'a, DedupFuncType>,
493 tables: SliceIter<'a, TableType>,
494 memories: SliceIter<'a, MemoryType>,
495 globals: SliceIter<'a, GlobalType>,
496}
497
498impl<'a> Iterator for ModuleImportsIter<'a> {
499 type Item = ImportType<'a>;
500
501 fn next(&mut self) -> Option<Self::Item> {
502 let import = match self.names.next() {
503 None => return None,
504 Some(imported) => match imported {
505 Imported::Func(name) => {
506 let func_type = self.funcs.next().unwrap_or_else(|| {
507 panic!("unexpected missing imported function for {name:?}")
508 });
509 let func_type = self.engine.resolve_func_type(func_type, FuncType::clone);
510 ImportType::new(name, func_type)
511 }
512 Imported::Table(name) => {
513 let table_type = self.tables.next().unwrap_or_else(|| {
514 panic!("unexpected missing imported table for {name:?}")
515 });
516 ImportType::new(name, *table_type)
517 }
518 Imported::Memory(name) => {
519 let memory_type = self.memories.next().unwrap_or_else(|| {
520 panic!("unexpected missing imported linear memory for {name:?}")
521 });
522 ImportType::new(name, *memory_type)
523 }
524 Imported::Global(name) => {
525 let global_type = self.globals.next().unwrap_or_else(|| {
526 panic!("unexpected missing imported global variable for {name:?}")
527 });
528 ImportType::new(name, *global_type)
529 }
530 },
531 };
532 Some(import)
533 }
534
535 fn size_hint(&self) -> (usize, Option<usize>) {
536 self.names.size_hint()
537 }
538}
539
540impl<'a> ExactSizeIterator for ModuleImportsIter<'a> {
541 fn len(&self) -> usize {
542 ExactSizeIterator::len(&self.names)
543 }
544}
545
546#[derive(Debug)]
552pub struct ImportType<'module> {
553 name: &'module ImportName,
555 ty: ExternType,
557}
558
559impl<'module> ImportType<'module> {
560 pub(crate) fn new<T>(name: &'module ImportName, ty: T) -> Self
562 where
563 T: Into<ExternType>,
564 {
565 Self {
566 name,
567 ty: ty.into(),
568 }
569 }
570
571 pub(crate) fn import_name(&self) -> &ImportName {
573 self.name
574 }
575
576 pub fn module(&self) -> &'module str {
578 self.name.module()
579 }
580
581 pub fn name(&self) -> &'module str {
583 self.name.name()
584 }
585
586 pub fn ty(&self) -> &ExternType {
588 &self.ty
589 }
590}
591
592#[derive(Debug)]
594pub struct InternalFuncsIter<'a> {
595 iter: iter::Zip<SliceIter<'a, DedupFuncType>, EngineFuncSpanIter>,
596}
597
598impl<'a> Iterator for InternalFuncsIter<'a> {
599 type Item = (DedupFuncType, EngineFunc);
600
601 fn next(&mut self) -> Option<Self::Item> {
602 self.iter
603 .next()
604 .map(|(func_type, engine_func)| (*func_type, engine_func))
605 }
606
607 fn size_hint(&self) -> (usize, Option<usize>) {
608 self.iter.size_hint()
609 }
610}
611
612impl<'a> ExactSizeIterator for InternalFuncsIter<'a> {
613 fn len(&self) -> usize {
614 ExactSizeIterator::len(&self.iter)
615 }
616}
617
618#[derive(Debug)]
620pub struct InternalGlobalsIter<'a> {
621 iter: iter::Zip<SliceIter<'a, GlobalType>, SliceIter<'a, ConstExpr>>,
622}
623
624impl<'a> Iterator for InternalGlobalsIter<'a> {
625 type Item = (&'a GlobalType, &'a ConstExpr);
626
627 fn next(&mut self) -> Option<Self::Item> {
628 self.iter.next()
629 }
630
631 fn size_hint(&self) -> (usize, Option<usize>) {
632 self.iter.size_hint()
633 }
634}
635
636impl<'a> ExactSizeIterator for InternalGlobalsIter<'a> {
637 fn len(&self) -> usize {
638 ExactSizeIterator::len(&self.iter)
639 }
640}