/src/wasmer/lib/compiler/src/translator/state.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file contains code from external sources. |
2 | | // Attributions: https://github.com/wasmerio/wasmer/blob/main/docs/ATTRIBUTIONS.md |
3 | | |
4 | | use std::boxed::Box; |
5 | | use wasmer_types::entity::PrimaryMap; |
6 | | use wasmer_types::{SignatureIndex, WasmResult}; |
7 | | |
8 | | /// Map of signatures to a function's parameter and return types. |
9 | | pub(crate) type WasmTypes = |
10 | | PrimaryMap<SignatureIndex, (Box<[wasmparser::ValType]>, Box<[wasmparser::ValType]>)>; |
11 | | |
12 | | /// Contains information decoded from the Wasm module that must be referenced |
13 | | /// during each Wasm function's translation. |
14 | | /// |
15 | | /// This is only for data that is maintained by `wasmer-compiler` itself, as |
16 | | /// opposed to being maintained by the embedder. Data that is maintained by the |
17 | | /// embedder is represented with `ModuleEnvironment`. |
18 | | #[derive(Debug)] |
19 | | pub struct ModuleTranslationState { |
20 | | /// A map containing a Wasm module's original, raw signatures. |
21 | | /// |
22 | | /// This is used for translating multi-value Wasm blocks inside functions, |
23 | | /// which are encoded to refer to their type signature via index. |
24 | | pub(crate) wasm_types: WasmTypes, |
25 | | } |
26 | | |
27 | | impl ModuleTranslationState { |
28 | | /// Creates a new empty ModuleTranslationState. |
29 | 84.9k | pub fn new() -> Self { |
30 | 84.9k | Self { |
31 | 84.9k | wasm_types: PrimaryMap::new(), |
32 | 84.9k | } |
33 | 84.9k | } <wasmer_compiler::translator::state::ModuleTranslationState>::new Line | Count | Source | 29 | 60.5k | pub fn new() -> Self { | 30 | 60.5k | Self { | 31 | 60.5k | wasm_types: PrimaryMap::new(), | 32 | 60.5k | } | 33 | 60.5k | } |
<wasmer_compiler::translator::state::ModuleTranslationState>::new Line | Count | Source | 29 | 24.4k | pub fn new() -> Self { | 30 | 24.4k | Self { | 31 | 24.4k | wasm_types: PrimaryMap::new(), | 32 | 24.4k | } | 33 | 24.4k | } |
|
34 | | |
35 | | /// Get the parameter and result types for the given Wasm blocktype. |
36 | 333k | pub fn blocktype_params_results<'a>( |
37 | 333k | &'a self, |
38 | 333k | ty_or_ft: &'a wasmparser::BlockType, |
39 | 333k | ) -> WasmResult<(&'a [wasmparser::ValType], SingleOrMultiValue<'a>)> { |
40 | 333k | Ok(match ty_or_ft { |
41 | 252k | wasmparser::BlockType::Type(ty) => (&[], SingleOrMultiValue::Single(ty)), |
42 | 6.64k | wasmparser::BlockType::FuncType(ty_index) => { |
43 | 6.64k | let sig_idx = SignatureIndex::from_u32(*ty_index); |
44 | 6.64k | let (ref params, ref results) = self.wasm_types[sig_idx]; |
45 | 6.64k | (params, SingleOrMultiValue::Multi(results.as_ref())) |
46 | | } |
47 | 74.4k | wasmparser::BlockType::Empty => (&[], SingleOrMultiValue::Multi(&[])), |
48 | | }) |
49 | 333k | } <wasmer_compiler::translator::state::ModuleTranslationState>::blocktype_params_results Line | Count | Source | 36 | 333k | pub fn blocktype_params_results<'a>( | 37 | 333k | &'a self, | 38 | 333k | ty_or_ft: &'a wasmparser::BlockType, | 39 | 333k | ) -> WasmResult<(&'a [wasmparser::ValType], SingleOrMultiValue<'a>)> { | 40 | 333k | Ok(match ty_or_ft { | 41 | 252k | wasmparser::BlockType::Type(ty) => (&[], SingleOrMultiValue::Single(ty)), | 42 | 6.64k | wasmparser::BlockType::FuncType(ty_index) => { | 43 | 6.64k | let sig_idx = SignatureIndex::from_u32(*ty_index); | 44 | 6.64k | let (ref params, ref results) = self.wasm_types[sig_idx]; | 45 | 6.64k | (params, SingleOrMultiValue::Multi(results.as_ref())) | 46 | | } | 47 | 74.4k | wasmparser::BlockType::Empty => (&[], SingleOrMultiValue::Multi(&[])), | 48 | | }) | 49 | 333k | } |
Unexecuted instantiation: <wasmer_compiler::translator::state::ModuleTranslationState>::blocktype_params_results |
50 | | } |
51 | | |
52 | | /// A helper enum for representing either a single or multiple values. |
53 | | pub enum SingleOrMultiValue<'a> { |
54 | | /// A single value. |
55 | | Single(&'a wasmparser::ValType), |
56 | | /// Multiple values. |
57 | | Multi(&'a [wasmparser::ValType]), |
58 | | } |
59 | | |
60 | | impl<'a> SingleOrMultiValue<'a> { |
61 | | /// True if empty. |
62 | 0 | pub fn is_empty(&self) -> bool { |
63 | 0 | match self { |
64 | 0 | SingleOrMultiValue::Single(_) => false, |
65 | 0 | SingleOrMultiValue::Multi(values) => values.is_empty(), |
66 | | } |
67 | 0 | } Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::is_empty Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::is_empty |
68 | | |
69 | | /// Count of values. |
70 | 153k | pub fn len(&self) -> usize { |
71 | 153k | match self { |
72 | 119k | SingleOrMultiValue::Single(_) => 1, |
73 | 34.0k | SingleOrMultiValue::Multi(values) => values.len(), |
74 | | } |
75 | 153k | } <wasmer_compiler::translator::state::SingleOrMultiValue>::len Line | Count | Source | 70 | 153k | pub fn len(&self) -> usize { | 71 | 153k | match self { | 72 | 119k | SingleOrMultiValue::Single(_) => 1, | 73 | 34.0k | SingleOrMultiValue::Multi(values) => values.len(), | 74 | | } | 75 | 153k | } |
Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::len Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::len Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::len |
76 | | |
77 | | /// Iterate ofer the value types. |
78 | 326k | pub fn iter(&self) -> SingleOrMultiValueIterator<'_> { |
79 | 326k | match self { |
80 | 247k | SingleOrMultiValue::Single(v) => SingleOrMultiValueIterator::Single(v), |
81 | 78.3k | SingleOrMultiValue::Multi(items) => SingleOrMultiValueIterator::Multi { |
82 | 78.3k | index: 0, |
83 | 78.3k | values: items, |
84 | 78.3k | }, |
85 | | } |
86 | 326k | } <wasmer_compiler::translator::state::SingleOrMultiValue>::iter Line | Count | Source | 78 | 172k | pub fn iter(&self) -> SingleOrMultiValueIterator<'_> { | 79 | 172k | match self { | 80 | 128k | SingleOrMultiValue::Single(v) => SingleOrMultiValueIterator::Single(v), | 81 | 44.2k | SingleOrMultiValue::Multi(items) => SingleOrMultiValueIterator::Multi { | 82 | 44.2k | index: 0, | 83 | 44.2k | values: items, | 84 | 44.2k | }, | 85 | | } | 86 | 172k | } |
<wasmer_compiler::translator::state::SingleOrMultiValue>::iter Line | Count | Source | 78 | 153k | pub fn iter(&self) -> SingleOrMultiValueIterator<'_> { | 79 | 153k | match self { | 80 | 119k | SingleOrMultiValue::Single(v) => SingleOrMultiValueIterator::Single(v), | 81 | 34.0k | SingleOrMultiValue::Multi(items) => SingleOrMultiValueIterator::Multi { | 82 | 34.0k | index: 0, | 83 | 34.0k | values: items, | 84 | 34.0k | }, | 85 | | } | 86 | 153k | } |
Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::iter Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::iter Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue>::iter |
87 | | } |
88 | | |
89 | | pub enum SingleOrMultiValueIterator<'a> { |
90 | | Done, |
91 | | Single(&'a wasmparser::ValType), |
92 | | Multi { |
93 | | index: usize, |
94 | | values: &'a [wasmparser::ValType], |
95 | | }, |
96 | | } |
97 | | |
98 | | impl<'a> Iterator for SingleOrMultiValueIterator<'a> { |
99 | | type Item = &'a wasmparser::ValType; |
100 | | |
101 | 627k | fn next(&mut self) -> Option<Self::Item> { |
102 | 627k | match self { |
103 | 247k | SingleOrMultiValueIterator::Done => None, |
104 | 247k | SingleOrMultiValueIterator::Single(v) => { |
105 | 247k | let v = *v; |
106 | 247k | *self = SingleOrMultiValueIterator::Done; |
107 | 247k | Some(v) |
108 | | } |
109 | 131k | SingleOrMultiValueIterator::Multi { index, values } => { |
110 | 131k | if let Some(x) = values.get(*index) { |
111 | 53.1k | *index += 1; |
112 | 53.1k | Some(x) |
113 | | } else { |
114 | 78.3k | *self = SingleOrMultiValueIterator::Done; |
115 | 78.3k | None |
116 | | } |
117 | | } |
118 | | } |
119 | 627k | } <wasmer_compiler::translator::state::SingleOrMultiValueIterator as core::iter::traits::iterator::Iterator>::next Line | Count | Source | 101 | 627k | fn next(&mut self) -> Option<Self::Item> { | 102 | 627k | match self { | 103 | 247k | SingleOrMultiValueIterator::Done => None, | 104 | 247k | SingleOrMultiValueIterator::Single(v) => { | 105 | 247k | let v = *v; | 106 | 247k | *self = SingleOrMultiValueIterator::Done; | 107 | 247k | Some(v) | 108 | | } | 109 | 131k | SingleOrMultiValueIterator::Multi { index, values } => { | 110 | 131k | if let Some(x) = values.get(*index) { | 111 | 53.1k | *index += 1; | 112 | 53.1k | Some(x) | 113 | | } else { | 114 | 78.3k | *self = SingleOrMultiValueIterator::Done; | 115 | 78.3k | None | 116 | | } | 117 | | } | 118 | | } | 119 | 627k | } |
Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValueIterator as core::iter::traits::iterator::Iterator>::next |
120 | | } |
121 | | |
122 | | impl<'a> PartialEq<[wasmparser::ValType]> for SingleOrMultiValue<'a> { |
123 | 0 | fn eq(&self, other: &[wasmparser::ValType]) -> bool { |
124 | 0 | match self { |
125 | 0 | SingleOrMultiValue::Single(ty) => other.len() == 1 && &other[0] == *ty, |
126 | 0 | SingleOrMultiValue::Multi(tys) => *tys == other, |
127 | | } |
128 | 0 | } Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue as core::cmp::PartialEq<[wasmparser::readers::core::types::ValType]>>::eq Unexecuted instantiation: <wasmer_compiler::translator::state::SingleOrMultiValue as core::cmp::PartialEq<[wasmparser::readers::core::types::ValType]>>::eq |
129 | | } |
130 | | |
131 | | impl<'a> PartialEq<SingleOrMultiValue<'a>> for &'a [wasmparser::ValType] { |
132 | 5.34k | fn eq(&self, other: &SingleOrMultiValue<'a>) -> bool { |
133 | 5.34k | match other { |
134 | 4.05k | SingleOrMultiValue::Single(ty) => self.len() == 1 && &self[0] == *ty, |
135 | 1.29k | SingleOrMultiValue::Multi(tys) => tys == self, |
136 | | } |
137 | 5.34k | } <&[wasmparser::readers::core::types::ValType] as core::cmp::PartialEq<wasmer_compiler::translator::state::SingleOrMultiValue>>::eq Line | Count | Source | 132 | 5.34k | fn eq(&self, other: &SingleOrMultiValue<'a>) -> bool { | 133 | 5.34k | match other { | 134 | 4.05k | SingleOrMultiValue::Single(ty) => self.len() == 1 && &self[0] == *ty, | 135 | 1.29k | SingleOrMultiValue::Multi(tys) => tys == self, | 136 | | } | 137 | 5.34k | } |
Unexecuted instantiation: <&[wasmparser::readers::core::types::ValType] as core::cmp::PartialEq<wasmer_compiler::translator::state::SingleOrMultiValue>>::eq |
138 | | } |