1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
#[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; /// Controls which experimental features will be enabled. /// Features usually have a corresponding [WebAssembly proposal]. /// /// [WebAssembly proposal]: https://github.com/WebAssembly/proposals #[derive(Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct Features { /// Threads proposal should be enabled pub threads: bool, /// Reference Types proposal should be enabled pub reference_types: bool, /// SIMD proposal should be enabled pub simd: bool, /// Bulk Memory proposal should be enabled pub bulk_memory: bool, /// Multi Value proposal should be enabled pub multi_value: bool, } impl Features { /// Create a new feature pub fn new() -> Self { Self { threads: false, reference_types: false, simd: false, // Bulk Memory should be on by default bulk_memory: true, // Multivalue should be on by default multi_value: true, } } /// Configures whether the WebAssembly threads proposal will be enabled. /// /// The [WebAssembly threads proposal][threads] is not currently fully /// standardized and is undergoing development. Support for this feature can /// be enabled through this method for appropriate WebAssembly modules. /// /// This feature gates items such as shared memories and atomic /// instructions. /// /// This is `false` by default. /// /// [threads]: https://github.com/webassembly/threads pub fn threads(&mut self, enable: bool) -> &mut Self { self.threads = enable; self } /// Configures whether the WebAssembly reference types proposal will be /// enabled. /// /// The [WebAssembly reference types proposal][proposal] is not currently /// fully standardized and is undergoing development. Support for this /// feature can be enabled through this method for appropriate WebAssembly /// modules. /// /// This feature gates items such as the `externref` type and multiple tables /// being in a module. Note that enabling the reference types feature will /// also enable the bulk memory feature. /// /// This is `false` by default. /// /// [proposal]: https://github.com/webassembly/reference-types pub fn reference_types(&mut self, enable: bool) -> &mut Self { self.reference_types = enable; // The reference types proposal depends on the bulk memory proposal if enable { self.bulk_memory(true); } self } /// Configures whether the WebAssembly SIMD proposal will be /// enabled. /// /// The [WebAssembly SIMD proposal][proposal] is not currently /// fully standardized and is undergoing development. Support for this /// feature can be enabled through this method for appropriate WebAssembly /// modules. /// /// This feature gates items such as the `v128` type and all of its /// operators being in a module. /// /// This is `false` by default. /// /// [proposal]: https://github.com/webassembly/simd pub fn simd(&mut self, enable: bool) -> &mut Self { self.simd = enable; self } /// Configures whether the WebAssembly bulk memory operations proposal will /// be enabled. /// /// The [WebAssembly bulk memory operations proposal][proposal] is not /// currently fully standardized and is undergoing development. /// Support for this feature can be enabled through this method for /// appropriate WebAssembly modules. /// /// This feature gates items such as the `memory.copy` instruction, passive /// data/table segments, etc, being in a module. /// /// This is `false` by default. /// /// [proposal]: https://github.com/webassembly/bulk-memory-operations pub fn bulk_memory(&mut self, enable: bool) -> &mut Self { self.bulk_memory = enable; // In case is false, we disable both threads and reference types // since they both depend on bulk memory if !enable { self.reference_types(false); } self } /// Configures whether the WebAssembly multi-value proposal will /// be enabled. /// /// The [WebAssembly multi-value proposal][proposal] is not /// currently fully standardized and is undergoing development. /// Support for this feature can be enabled through this method for /// appropriate WebAssembly modules. /// /// This feature gates functions and blocks returning multiple values in a /// module, for example. /// /// This is `false` by default. /// /// [proposal]: https://github.com/webassembly/multi-value pub fn multi_value(&mut self, enable: bool) -> &mut Self { self.multi_value = enable; self } } impl Default for Features { fn default() -> Self { Self::new() } } #[cfg(test)] mod test_features { use super::*; #[test] fn default_features() { let default = Features::default(); assert_eq!( default, Features { threads: false, reference_types: false, simd: false, bulk_memory: true, multi_value: true, } ); } #[test] fn enable_threads() { let mut features = Features::new(); features.bulk_memory(false).threads(true); assert!(features.threads); } #[test] fn enable_reference_types() { let mut features = Features::new(); features.bulk_memory(false).reference_types(true); assert!(features.reference_types); assert!(features.bulk_memory); } #[test] fn enable_simd() { let mut features = Features::new(); features.simd(true); assert!(features.simd); } #[test] fn enable_multi_value() { let mut features = Features::new(); features.multi_value(true); assert!(features.multi_value); } #[test] fn enable_bulk_memory() { let mut features = Features::new(); features.bulk_memory(true); assert!(features.bulk_memory); } #[test] fn disable_bulk_memory() { let mut features = Features::new(); features .threads(true) .reference_types(true) .bulk_memory(false); assert!(!features.bulk_memory); assert!(!features.reference_types); } }