Skip to content

Commit e66756b

Browse files
authored
reencoder: allow implementers to fail to reencode indices and such (#2179)
I have found myself wanting to return an error from `Reencode::type_index`. This is admittedly a pretty invasive change though and I punted on component stuff.
1 parent d2c36f4 commit e66756b

File tree

8 files changed

+323
-252
lines changed

8 files changed

+323
-252
lines changed

crates/wasm-encoder/src/reencode.rs

Lines changed: 173 additions & 129 deletions
Large diffs are not rendered by default.

crates/wasm-encoder/src/reencode/component.rs

Lines changed: 101 additions & 76 deletions
Large diffs are not rendered by default.

crates/wasm-mutate/src/mutators/modify_const_exprs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ impl<'cfg, 'wasm> Reencode for InitTranslator<'cfg, 'wasm> {
4040

4141
/// Handle `elem`s with values of the `ElementItem::Func` kind. This function will not be
4242
/// called for values of the `ElementItem::Expr` kind.
43-
fn function_index(&mut self, idx: u32) -> u32 {
43+
fn function_index(&mut self, idx: u32) -> ReencodeResult<u32> {
4444
if self.kind != ConstExpressionMutator::ElementFunc || !self.should_process() {
45-
return idx;
45+
return Ok(idx);
4646
}
4747

4848
log::trace!("... replacing referenced function index with 0");
4949
// FIXME: generate random function indices when `!config.reduce`.
50-
0
50+
Ok(0)
5151
}
5252

5353
/// Handle `global` initializers and `elem`s with values of the `ElementItem::Expr` kind.

crates/wasm-mutate/src/mutators/remove_item.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl RemoveItem<'_> {
187187
/// try something else.
188188
/// * Finally our index is larger than the one being removed which means we
189189
/// now decrement it by one to account for the removed item.
190-
fn remap(&mut self, item: Item, idx: u32) -> u32 {
190+
fn remap(&mut self, item: Item, idx: u32) -> ReencodeResult<u32> {
191191
// If we're before the code section then all function references, no
192192
// matter where they are, are considered "referencing functions" so we
193193
// save the indices of that which is referenced.
@@ -197,7 +197,7 @@ impl RemoveItem<'_> {
197197
}
198198
}
199199

200-
if item != self.item || idx < self.idx {
200+
Ok(if item != self.item || idx < self.idx {
201201
// Different kind of item or a later item was removed, index doesn't change
202202
idx
203203
} else if idx == self.idx {
@@ -210,42 +210,42 @@ impl RemoveItem<'_> {
210210
// Otherwise this item comes after the item being removed, so
211211
// this item's index has decreased by one.
212212
idx - 1
213-
}
213+
})
214214
}
215215
}
216216

217217
impl Reencode for RemoveItem<'_> {
218218
type Error = Error;
219219

220-
fn function_index(&mut self, idx: u32) -> u32 {
220+
fn function_index(&mut self, idx: u32) -> ReencodeResult<u32> {
221221
self.remap(Item::Function, idx)
222222
}
223223

224-
fn table_index(&mut self, idx: u32) -> u32 {
224+
fn table_index(&mut self, idx: u32) -> ReencodeResult<u32> {
225225
self.remap(Item::Table, idx)
226226
}
227227

228-
fn memory_index(&mut self, idx: u32) -> u32 {
228+
fn memory_index(&mut self, idx: u32) -> ReencodeResult<u32> {
229229
self.remap(Item::Memory, idx)
230230
}
231231

232-
fn tag_index(&mut self, idx: u32) -> u32 {
232+
fn tag_index(&mut self, idx: u32) -> ReencodeResult<u32> {
233233
self.remap(Item::Tag, idx)
234234
}
235235

236-
fn global_index(&mut self, idx: u32) -> u32 {
236+
fn global_index(&mut self, idx: u32) -> ReencodeResult<u32> {
237237
self.remap(Item::Global, idx)
238238
}
239239

240-
fn type_index(&mut self, idx: u32) -> u32 {
240+
fn type_index(&mut self, idx: u32) -> ReencodeResult<u32> {
241241
self.remap(Item::Type, idx)
242242
}
243243

244-
fn data_index(&mut self, idx: u32) -> u32 {
244+
fn data_index(&mut self, idx: u32) -> ReencodeResult<u32> {
245245
self.remap(Item::Data, idx)
246246
}
247247

248-
fn element_index(&mut self, idx: u32) -> u32 {
248+
fn element_index(&mut self, idx: u32) -> ReencodeResult<u32> {
249249
self.remap(Item::Element, idx)
250250
}
251251

@@ -312,7 +312,7 @@ impl Reencode for RemoveItem<'_> {
312312
section: wasmparser::FunctionSectionReader<'_>,
313313
) -> ReencodeResult<()> {
314314
self.filter_out(section, Item::Function, |me, func| {
315-
funcs.function(me.type_index(func));
315+
funcs.function(me.type_index(func)?);
316316
Ok(())
317317
})
318318
}
@@ -334,7 +334,7 @@ impl Reencode for RemoveItem<'_> {
334334
section: wasmparser::MemorySectionReader<'_>,
335335
) -> ReencodeResult<()> {
336336
self.filter_out(section, Item::Memory, |me, memory| {
337-
memories.memory(me.memory_type(memory));
337+
memories.memory(me.memory_type(memory)?);
338338
Ok(())
339339
})
340340
}
@@ -378,23 +378,23 @@ impl Reencode for RemoveItem<'_> {
378378
section: wasmparser::TagSectionReader<'_>,
379379
) -> ReencodeResult<()> {
380380
self.filter_out(section, Item::Tag, |me, tag| {
381-
tags.tag(me.tag_type(tag));
381+
tags.tag(me.tag_type(tag)?);
382382
Ok(())
383383
})
384384
}
385385

386-
fn data_count(&mut self, count: u32) -> u32 {
386+
fn data_count(&mut self, count: u32) -> ReencodeResult<u32> {
387387
// Note that the data count section is decremented here if
388388
// we're removing a data item, otherwise it's preserved
389389
// as-is.
390-
if self.item == Item::Data {
390+
Ok(if self.item == Item::Data {
391391
count - 1
392392
} else {
393393
count
394-
}
394+
})
395395
}
396396

397-
fn start_section(&mut self, func: u32) -> u32 {
397+
fn start_section(&mut self, func: u32) -> ReencodeResult<u32> {
398398
self.function_reference_action = Funcref::Skip;
399399
let func = self.remap(Item::Function, func);
400400
self.function_reference_action = Funcref::Save;

crates/wit-component/src/encoding/dedupe.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::{
1313
};
1414
use wasm_encoder::{
1515
self,
16-
reencode::{utils::parse_custom_section, Reencode},
16+
reencode::{self, utils::parse_custom_section, Reencode},
1717
};
1818
use wasmparser::{self, BinaryReaderError, Import, KnownCustom, Parser, TypeRef};
1919

@@ -138,7 +138,7 @@ struct DedupingReencoder {
138138
remappings: Remappings,
139139
}
140140

141-
type DeduperError = wasm_encoder::reencode::Error<NoDuplicatesFound>;
141+
type DeduperError = reencode::Error<NoDuplicatesFound>;
142142

143143
impl Reencode for DedupingReencoder {
144144
type Error = NoDuplicatesFound;
@@ -149,7 +149,7 @@ impl Reencode for DedupingReencoder {
149149
&mut self,
150150
imports: &mut wasm_encoder::ImportSection,
151151
section: wasmparser::ImportSectionReader<'_>,
152-
) -> Result<(), wasm_encoder::reencode::Error<Self::Error>> {
152+
) -> Result<(), reencode::Error<Self::Error>> {
153153
self.remappings.imports(section.clone())?;
154154

155155
// If no duplicates, take the fast path out.
@@ -165,8 +165,8 @@ impl Reencode for DedupingReencoder {
165165
Ok(())
166166
}
167167

168-
fn function_index(&mut self, func_idx: u32) -> u32 {
169-
self.remappings.new_index_for(func_idx)
168+
fn function_index(&mut self, func_idx: u32) -> Result<u32, reencode::Error<Self::Error>> {
169+
Ok(self.remappings.new_index_for(func_idx))
170170
}
171171

172172
// Strip all but known-safe custom sections.
@@ -181,7 +181,7 @@ impl Reencode for DedupingReencoder {
181181
&mut self,
182182
module: &mut wasm_encoder::Module,
183183
section: wasmparser::CustomSectionReader<'_>,
184-
) -> Result<(), wasm_encoder::reencode::Error<Self::Error>> {
184+
) -> Result<(), reencode::Error<Self::Error>> {
185185
match section.as_known() {
186186
KnownCustom::Name(_) | KnownCustom::Producers(_) => {
187187
// Keep this section verbatim:

crates/wit-component/src/gc.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,10 @@ impl<'a> Module<'a> {
538538
let ty = map.memory_type(mem.ty);
539539
match &mem.def {
540540
Definition::Import(m, n) => {
541-
imports.import(m, n, ty);
541+
imports.import(m, n, ty?);
542542
}
543543
Definition::Local(()) => {
544-
memories.memory(ty);
544+
memories.memory(ty?);
545545
}
546546
}
547547
num_memories += 1;
@@ -1030,23 +1030,25 @@ struct Encoder {
10301030
tables: Remap,
10311031
}
10321032

1033+
type ReencodeResult<T> = Result<T, wasm_encoder::reencode::Error<Infallible>>;
1034+
10331035
impl Reencode for Encoder {
10341036
type Error = Infallible;
10351037

1036-
fn type_index(&mut self, i: u32) -> u32 {
1037-
self.types.remap(i)
1038+
fn type_index(&mut self, i: u32) -> ReencodeResult<u32> {
1039+
Ok(self.types.remap(i))
10381040
}
1039-
fn function_index(&mut self, i: u32) -> u32 {
1040-
self.funcs.remap(i)
1041+
fn function_index(&mut self, i: u32) -> ReencodeResult<u32> {
1042+
Ok(self.funcs.remap(i))
10411043
}
1042-
fn memory_index(&mut self, i: u32) -> u32 {
1043-
self.memories.remap(i)
1044+
fn memory_index(&mut self, i: u32) -> ReencodeResult<u32> {
1045+
Ok(self.memories.remap(i))
10441046
}
1045-
fn global_index(&mut self, i: u32) -> u32 {
1046-
self.globals.remap(i)
1047+
fn global_index(&mut self, i: u32) -> ReencodeResult<u32> {
1048+
Ok(self.globals.remap(i))
10471049
}
1048-
fn table_index(&mut self, i: u32) -> u32 {
1049-
self.tables.remap(i)
1050+
fn table_index(&mut self, i: u32) -> ReencodeResult<u32> {
1051+
Ok(self.tables.remap(i))
10501052
}
10511053
}
10521054

fuzz/src/roundtrip_wit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ struct RemoveImports<'a, 'b> {
171171
impl Reencode for RemoveImports<'_, '_> {
172172
type Error = std::convert::Infallible;
173173

174-
fn function_index(&mut self, idx: u32) -> u32 {
175-
idx - self.removed_funcs
174+
fn function_index(&mut self, idx: u32) -> Result<u32, reencode::Error<Self::Error>> {
175+
Ok(idx - self.removed_funcs)
176176
}
177177

178178
fn parse_import(

src/bin/wasm-tools/component.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,12 +1273,12 @@ struct ModuleExtractor<'a> {
12731273
impl Reencode for ModuleExtractor<'_> {
12741274
type Error = std::convert::Infallible;
12751275

1276-
fn type_index(&mut self, index: u32) -> u32 {
1277-
if self.depth == 0 {
1276+
fn type_index(&mut self, index: u32) -> Result<u32, Error<Self::Error>> {
1277+
Ok(if self.depth == 0 {
12781278
index + self.extra_core_types
12791279
} else {
12801280
index
1281-
}
1281+
})
12821282
}
12831283
}
12841284

@@ -1291,12 +1291,12 @@ impl ReencodeComponent for ModuleExtractor<'_> {
12911291
}
12921292
}
12931293

1294-
fn outer_type_index(&mut self, count: u32, index: u32) -> u32 {
1295-
if self.depth == count {
1294+
fn outer_type_index(&mut self, count: u32, index: u32) -> Result<u32, Error<Self::Error>> {
1295+
Ok(if self.depth == count {
12961296
index + self.extra_core_types
12971297
} else {
12981298
index
1299-
}
1299+
})
13001300
}
13011301

13021302
fn outer_module_index(&mut self, count: u32, index: u32) -> u32 {

0 commit comments

Comments
 (0)