1 use crate::ModuleContext;
2 use std::collections::HashMap;
3 
4 /// Wizer-specific contextual information about a component, returned from
5 /// [`Wizer::instrument_component`].
6 ///
7 /// [`Wizer::instrument_component`]: crate::Wizer::instrument_component
8 #[derive(Default)]
9 pub struct ComponentContext<'a> {
10     /// Sections of the component, which are either raw bytes or a parsed module
11     /// using `ModuleContext`.
12     pub(crate) sections: Vec<RawSection<'a>>,
13 
14     /// Counts of each index space for what this component contains.
15     ///
16     /// Note that these aren't all index spaces in the component, only those
17     /// needed at this time.
18     pub(crate) instances: u32,
19     pub(crate) funcs: u32,
20     pub(crate) types: u32,
21     pub(crate) core_instances: u32,
22     pub(crate) core_memories: u32,
23     pub(crate) core_funcs: u32,
24 
25     /// Map of which module index to the core instance index it's instantiated
26     /// as.
27     pub(crate) core_instantiations: HashMap<u32, u32>,
28 
29     /// Instrumentation injected to access internal state of globals/memories.
30     pub(crate) accessors: Option<Vec<Accessor>>,
31 }
32 
33 /// Generated accessors during instrumentation and the metadata about them.
34 pub(crate) enum Accessor {
35     /// This accessor retrieves the value of a wasm global.
36     Global {
37         /// The module index, within the parent component, that this global
38         /// belongs to.
39         module_index: u32,
40 
41         /// The wizer-instrumented name of the global export this is accessing.
42         core_export_name: String,
43 
44         /// The component level export name to access this global.
45         accessor_export_name: String,
46 
47         /// The content type of this global.
48         ty: wasmparser::ValType,
49     },
50 
51     /// This accessor retrieves the value of a wasm linear memory as a
52     /// `list<u8>` in WIT.
53     Memory {
54         /// The module index, within the parent component, that this memory
55         /// belongs to.
56         module_index: u32,
57 
58         /// The wizer-instrumented name of the memory export this is accessing.
59         core_export_name: String,
60 
61         /// The component level export name to access this memory.
62         accessor_export_name: String,
63     },
64 }
65 
66 /// A section of a component, learned during parsing.
67 pub(crate) enum RawSection<'a> {
68     /// A non-module section, whose raw contents are stored here.
69     Raw(wasm_encoder::RawSection<'a>),
70 
71     /// A module section, parsed as with Wizer's metadata.
72     Module(ModuleContext<'a>),
73 }
74 
75 impl<'a> ComponentContext<'a> {
push_raw_section(&mut self, section: wasm_encoder::RawSection<'a>)76     pub(crate) fn push_raw_section(&mut self, section: wasm_encoder::RawSection<'a>) {
77         self.sections.push(RawSection::Raw(section));
78     }
79 
push_module_section(&mut self, module: ModuleContext<'a>)80     pub(crate) fn push_module_section(&mut self, module: ModuleContext<'a>) {
81         self.sections.push(RawSection::Module(module));
82     }
83 
core_modules(&self) -> impl Iterator<Item = (u32, &ModuleContext<'a>)> + '_84     pub(crate) fn core_modules(&self) -> impl Iterator<Item = (u32, &ModuleContext<'a>)> + '_ {
85         let mut i = 0;
86         self.sections.iter().filter_map(move |s| match s {
87             RawSection::Module(m) => Some((inc(&mut i), m)),
88             RawSection::Raw(_) => None,
89         })
90     }
91 
num_core_modules(&self) -> u3292     pub(crate) fn num_core_modules(&self) -> u32 {
93         u32::try_from(self.core_modules().count()).unwrap()
94     }
95 
inc(&mut self, kind: wasmparser::ComponentExternalKind)96     pub(crate) fn inc(&mut self, kind: wasmparser::ComponentExternalKind) {
97         match kind {
98             wasmparser::ComponentExternalKind::Type => {
99                 self.inc_types();
100             }
101             wasmparser::ComponentExternalKind::Instance => {
102                 self.inc_instances();
103             }
104             wasmparser::ComponentExternalKind::Func => {
105                 self.inc_funcs();
106             }
107             wasmparser::ComponentExternalKind::Component
108             | wasmparser::ComponentExternalKind::Module
109             | wasmparser::ComponentExternalKind::Value => {}
110         }
111     }
112 
inc_core(&mut self, kind: wasmparser::ExternalKind)113     pub(crate) fn inc_core(&mut self, kind: wasmparser::ExternalKind) {
114         match kind {
115             wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
116                 self.inc_core_funcs();
117             }
118             wasmparser::ExternalKind::Memory => {
119                 self.inc_core_memories();
120             }
121             wasmparser::ExternalKind::Table
122             | wasmparser::ExternalKind::Global
123             | wasmparser::ExternalKind::Tag => {}
124         }
125     }
126 
inc_instances(&mut self) -> u32127     pub(crate) fn inc_instances(&mut self) -> u32 {
128         inc(&mut self.instances)
129     }
130 
inc_funcs(&mut self) -> u32131     pub(crate) fn inc_funcs(&mut self) -> u32 {
132         inc(&mut self.funcs)
133     }
134 
inc_core_memories(&mut self) -> u32135     pub(crate) fn inc_core_memories(&mut self) -> u32 {
136         inc(&mut self.core_memories)
137     }
138 
inc_types(&mut self) -> u32139     pub(crate) fn inc_types(&mut self) -> u32 {
140         inc(&mut self.types)
141     }
142 
inc_core_instances(&mut self) -> u32143     pub(crate) fn inc_core_instances(&mut self) -> u32 {
144         inc(&mut self.core_instances)
145     }
146 
inc_core_funcs(&mut self) -> u32147     pub(crate) fn inc_core_funcs(&mut self) -> u32 {
148         inc(&mut self.core_funcs)
149     }
150 }
151 
inc(count: &mut u32) -> u32152 fn inc(count: &mut u32) -> u32 {
153     let current = *count;
154     *count += 1;
155     current
156 }
157