Skip to content

Commit 677a922

Browse files
committed
Reduce verbosity in wasmparser Types API
This additionally applies to `TypesRef` and this PR applies a few changes: * Going from a `TypeId` to a `Type` is now done with `&types[id]` or `types.get(id)` instead of `type_from_id(id).unwrap()`. * All index-based accessors return a `T` instead of `Option<T>`. Fallibility is possible through the `*_count()` methods for embedders to test if necessary, but otherwise almost all accesses were followed by `.unwrap()` anyway. * Conversions from `Type` to a sub-component which were previously `as_foo_type(&self) -> Option<&Foo>` are now expressed as `unwrap_foo(&self) -> &Foo`. This renames `as` to `unwrap` to highlight the panicking behavior and additionally drops the `_type` suffix since that's implied on everything anyway. * The `type_at` function and its `core: bool` argument are removed in favor of `core_type_at` and `component_type_at` functions. * The `func_type_at` function was removed as it can be achieved through combining other functions. * Some methods which returned `&T` changed to return a `TypeId` which represents `T` for consistency. This is inspired by comments on #1094 and is something I've wanted to address for awhile and will ideally make the `Types` API a bit more ergonomic to use with fewer conversions and less `.unwrap()` boilerplate without any loss of functionality.
1 parent 1d71d2f commit 677a922

File tree

9 files changed

+398
-535
lines changed

9 files changed

+398
-535
lines changed

crates/wasm-compose/src/composer.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl<'a> CompositionGraphBuilder<'a> {
248248
let (_, component) = self.graph.get_component_of_instance(*instance_id).unwrap();
249249
match component.export_by_name(export) {
250250
Some((export_index, kind, index)) if kind == ComponentExternalKind::Instance => {
251-
let export_ty = component.types.component_instance_at(index).unwrap();
251+
let export_ty = component.types.component_instance_at(index);
252252
if !ComponentEntityType::is_subtype_of(
253253
&ComponentEntityType::Instance(export_ty),
254254
component.types(),
@@ -275,11 +275,9 @@ impl<'a> CompositionGraphBuilder<'a> {
275275
let component = self.graph.get_component(r.component).unwrap();
276276
let (name, ty) = component.import(r.import).unwrap();
277277
match ty {
278-
ComponentTypeRef::Instance(index) => (
279-
component,
280-
name,
281-
component.types.id_from_type_index(index, false).unwrap(),
282-
),
278+
ComponentTypeRef::Instance(index) => {
279+
(component, name, component.types.component_type_at(index))
280+
}
283281
_ => unreachable!("should not have an instance import ref to a non-instance import"),
284282
}
285283
}

crates/wasm-compose/src/encoding.rs

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,11 @@ impl<'a> TypeEncoder<'a> {
195195
) -> EntityType {
196196
match ty {
197197
wasmparser::types::EntityType::Func(id) => {
198-
let ty = self.0.type_from_id(id).unwrap();
198+
let ty = &self.0[id];
199199
let idx = match types.entry(PtrKey(ty)) {
200200
Entry::Occupied(e) => *e.get(),
201201
Entry::Vacant(e) => {
202-
let ty = ty.as_func_type().unwrap();
202+
let ty = ty.unwrap_func();
203203
let index = encodable.type_count();
204204
encodable.ty().function(
205205
ty.params().iter().copied().map(Self::val_type),
@@ -214,11 +214,11 @@ impl<'a> TypeEncoder<'a> {
214214
wasmparser::types::EntityType::Memory(ty) => EntityType::Memory(Self::memory_type(ty)),
215215
wasmparser::types::EntityType::Global(ty) => EntityType::Global(Self::global_type(ty)),
216216
wasmparser::types::EntityType::Tag(id) => {
217-
let ty = self.0.type_from_id(id).unwrap();
217+
let ty = &self.0[id];
218218
let idx = match types.entry(PtrKey(ty)) {
219219
Entry::Occupied(e) => *e.get(),
220220
Entry::Vacant(e) => {
221-
let ty = ty.as_func_type().unwrap();
221+
let ty = ty.unwrap_func();
222222
let index = encodable.type_count();
223223
encodable.ty().function(
224224
ty.params().iter().copied().map(Self::val_type),
@@ -341,11 +341,11 @@ impl<'a> TypeEncoder<'a> {
341341
types: &mut TypeMap<'a>,
342342
id: TypeId,
343343
) -> u32 {
344-
let ty = self.0.type_from_id(id).unwrap();
344+
let ty = &self.0[id];
345345
match types.entry(PtrKey(ty)) {
346346
Entry::Occupied(e) => *e.get(),
347347
Entry::Vacant(e) => {
348-
let ty = ty.as_module_type().unwrap();
348+
let ty = ty.unwrap_module();
349349

350350
let module = self.module(
351351
ty.imports
@@ -367,11 +367,11 @@ impl<'a> TypeEncoder<'a> {
367367
types: &mut TypeMap<'a>,
368368
id: TypeId,
369369
) -> u32 {
370-
let ty = self.0.type_from_id(id).unwrap();
370+
let ty = &self.0[id];
371371
match types.entry(PtrKey(ty)) {
372372
Entry::Occupied(e) => *e.get(),
373373
Entry::Vacant(e) => {
374-
let ty = ty.as_component_instance_type().unwrap();
374+
let ty = ty.unwrap_component_instance();
375375
let instance = self.instance(ty.exports.iter().map(|(n, t)| (n.as_str(), *t)));
376376
let index = encodable.type_count();
377377
encodable.ty().instance(&instance);
@@ -386,11 +386,11 @@ impl<'a> TypeEncoder<'a> {
386386
types: &mut TypeMap<'a>,
387387
id: TypeId,
388388
) -> u32 {
389-
let ty = self.0.type_from_id(id).unwrap();
389+
let ty = &self.0[id];
390390
match types.entry(PtrKey(ty)) {
391391
Entry::Occupied(e) => *e.get(),
392392
Entry::Vacant(e) => {
393-
let ty = ty.as_component_type().unwrap();
393+
let ty = ty.unwrap_component();
394394

395395
let component = self.component(
396396
ty.imports.iter().map(|(n, t)| (n.as_str(), *t)),
@@ -410,12 +410,12 @@ impl<'a> TypeEncoder<'a> {
410410
types: &mut TypeMap<'a>,
411411
id: TypeId,
412412
) -> u32 {
413-
let ty = self.0.type_from_id(id).unwrap();
413+
let ty = &self.0[id];
414414
if let Some(idx) = types.get(&PtrKey(ty)) {
415415
return *idx;
416416
}
417417

418-
let func_ty = ty.as_component_func_type().unwrap();
418+
let func_ty = ty.unwrap_component_func();
419419

420420
let params = func_ty
421421
.params
@@ -459,9 +459,7 @@ impl<'a> TypeEncoder<'a> {
459459
}
460460

461461
fn ty(&self, encodable: &mut impl Encodable, types: &mut TypeMap<'a>, id: TypeId) -> u32 {
462-
let ty = self.0.type_from_id(id).unwrap();
463-
464-
match ty {
462+
match &self.0[id] {
465463
Type::Sub(_) | Type::Instance(_) => {
466464
unreachable!()
467465
}
@@ -496,12 +494,12 @@ impl<'a> TypeEncoder<'a> {
496494
types: &mut TypeMap<'a>,
497495
id: TypeId,
498496
) -> u32 {
499-
let ty = self.0.type_from_id(id).unwrap();
497+
let ty = &self.0[id];
500498
if let Some(idx) = types.get(&PtrKey(ty)) {
501499
return *idx;
502500
}
503501

504-
let defined_ty = ty.as_defined_type().unwrap();
502+
let defined_ty = ty.unwrap_defined();
505503

506504
let index = match defined_ty {
507505
wasmparser::types::ComponentDefinedType::Primitive(ty) => {
@@ -694,7 +692,7 @@ impl<'a> TypeEncoder<'a> {
694692
let export = self.component_entity_type(encoded, types, export);
695693
if let Some(id) = id {
696694
// Update the index in the type map to point to this export
697-
let ty = self.0.type_from_id(id).unwrap();
695+
let ty = &self.0[id];
698696
types.insert(PtrKey(ty), encoded.type_count());
699697
}
700698
export
@@ -736,12 +734,8 @@ impl ArgumentImport<'_> {
736734
// If the existing import is an instance, convert this argument import to
737735
// a merged instance import.
738736
if let ArgumentImportKind::Item(component, ComponentEntityType::Instance(id)) = &self.kind {
739-
let exports = component
740-
.types
741-
.type_from_id(*id)
742-
.unwrap()
743-
.as_component_instance_type()
744-
.unwrap()
737+
let exports = component.types[*id]
738+
.unwrap_component_instance()
745739
.exports
746740
.iter();
747741

@@ -763,12 +757,8 @@ impl ArgumentImport<'_> {
763757
ArgumentImportKind::Instance(exports),
764758
ArgumentImportKind::Item(new_component, ComponentEntityType::Instance(id)),
765759
) => {
766-
for (name, new_type) in new_component
767-
.types
768-
.type_from_id(id)
769-
.unwrap()
770-
.as_component_instance_type()
771-
.unwrap()
760+
for (name, new_type) in new_component.types[id]
761+
.unwrap_component_instance()
772762
.exports
773763
.iter()
774764
{

crates/wasm-compose/src/graph.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,7 @@ impl<'a> Component<'a> {
286286
return false;
287287
}
288288
ComponentEntityType::is_subtype_of(
289-
&ComponentEntityType::Instance(
290-
self.types.component_instance_at(*index).unwrap(),
291-
),
289+
&ComponentEntityType::Instance(self.types.component_instance_at(*index)),
292290
self.types(),
293291
&ComponentEntityType::Instance(ty),
294292
types,
@@ -300,13 +298,7 @@ impl<'a> Component<'a> {
300298
/// Checks to see if an instance of this component would be a
301299
/// subtype of the given instance type.
302300
pub(crate) fn is_instance_subtype_of(&self, ty: TypeId, types: TypesRef) -> bool {
303-
let exports = types
304-
.type_from_id(ty)
305-
.unwrap()
306-
.as_component_instance_type()
307-
.unwrap()
308-
.exports
309-
.iter();
301+
let exports = types[ty].unwrap_component_instance().exports.iter();
310302

311303
for (k, b) in exports {
312304
match self.exports.get_full(k.as_str()) {

crates/wasmparser/src/validator.rs

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,67 +1441,52 @@ mod tests {
14411441
assert_eq!(types.instance_count(), 0);
14421442
assert_eq!(types.value_count(), 0);
14431443

1444-
match types.func_type_at(0) {
1445-
Some(ty) => {
1446-
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
1447-
assert_eq!(ty.results(), [ValType::I32]);
1448-
}
1449-
_ => unreachable!(),
1450-
}
1444+
let ty = types[types.core_type_at(0)].unwrap_func();
1445+
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
1446+
assert_eq!(ty.results(), [ValType::I32]);
14511447

1452-
match types.func_type_at(1) {
1453-
Some(ty) => {
1454-
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
1455-
assert_eq!(ty.results(), []);
1456-
}
1457-
_ => unreachable!(),
1458-
}
1448+
let ty = types[types.core_type_at(1)].unwrap_func();
1449+
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
1450+
assert_eq!(ty.results(), []);
14591451

14601452
assert_eq!(
14611453
types.memory_at(0),
1462-
Some(MemoryType {
1454+
MemoryType {
14631455
memory64: false,
14641456
shared: false,
14651457
initial: 1,
14661458
maximum: Some(5)
1467-
})
1459+
}
14681460
);
14691461

14701462
assert_eq!(
14711463
types.table_at(0),
1472-
Some(TableType {
1464+
TableType {
14731465
initial: 10,
14741466
maximum: None,
14751467
element_type: RefType::FUNCREF,
1476-
})
1468+
}
14771469
);
14781470

14791471
assert_eq!(
14801472
types.global_at(0),
1481-
Some(GlobalType {
1473+
GlobalType {
14821474
content_type: ValType::I32,
14831475
mutable: true
1484-
})
1476+
}
14851477
);
14861478

1487-
let id = types.function_at(0).unwrap();
1488-
match types.type_from_id(id).unwrap().as_func_type() {
1489-
Some(ty) => {
1490-
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
1491-
assert_eq!(ty.results(), [ValType::I32]);
1492-
}
1493-
_ => unreachable!(),
1494-
}
1479+
let id = types.function_at(0);
1480+
let ty = types[id].unwrap_func();
1481+
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
1482+
assert_eq!(ty.results(), [ValType::I32]);
14951483

1496-
match types.tag_at(0) {
1497-
Some(ty) => {
1498-
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
1499-
assert_eq!(ty.results(), []);
1500-
}
1501-
_ => unreachable!(),
1502-
}
1484+
let ty = types.tag_at(0);
1485+
let ty = types[ty].unwrap_func();
1486+
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
1487+
assert_eq!(ty.results(), []);
15031488

1504-
assert_eq!(types.element_at(0), Some(RefType::FUNCREF));
1489+
assert_eq!(types.element_at(0), RefType::FUNCREF);
15051490

15061491
Ok(())
15071492
}
@@ -1525,24 +1510,18 @@ mod tests {
15251510

15261511
let types = validator.validate_all(&bytes)?;
15271512

1528-
let t_id = types.id_from_type_index(0, false).unwrap();
1529-
let a1_id = types.id_from_type_index(1, false).unwrap();
1530-
let a2_id = types.id_from_type_index(2, false).unwrap();
1513+
let t_id = types.component_type_at(0);
1514+
let a1_id = types.component_type_at(1);
1515+
let a2_id = types.component_type_at(2);
15311516

15321517
// The ids should all be the same
15331518
assert!(t_id == a1_id);
15341519
assert!(t_id == a2_id);
15351520
assert!(a1_id == a2_id);
15361521

15371522
// However, they should all point to the same type
1538-
assert!(std::ptr::eq(
1539-
types.type_from_id(t_id).unwrap(),
1540-
types.type_from_id(a1_id).unwrap()
1541-
));
1542-
assert!(std::ptr::eq(
1543-
types.type_from_id(t_id).unwrap(),
1544-
types.type_from_id(a2_id).unwrap()
1545-
));
1523+
assert!(std::ptr::eq(&types[t_id], &types[a1_id],));
1524+
assert!(std::ptr::eq(&types[t_id], &types[a2_id],));
15461525

15471526
Ok(())
15481527
}
@@ -1566,24 +1545,18 @@ mod tests {
15661545

15671546
let types = validator.validate_all(&bytes)?;
15681547

1569-
let t_id = types.id_from_type_index(0, false).unwrap();
1570-
let a1_id = types.id_from_type_index(1, false).unwrap();
1571-
let a2_id = types.id_from_type_index(2, false).unwrap();
1548+
let t_id = types.component_type_at(0);
1549+
let a1_id = types.component_type_at(1);
1550+
let a2_id = types.component_type_at(2);
15721551

15731552
// The ids should all be the same
15741553
assert!(t_id != a1_id);
15751554
assert!(t_id != a2_id);
15761555
assert!(a1_id != a2_id);
15771556

15781557
// However, they should all point to the same type
1579-
assert!(std::ptr::eq(
1580-
types.type_from_id(t_id).unwrap(),
1581-
types.type_from_id(a1_id).unwrap()
1582-
));
1583-
assert!(std::ptr::eq(
1584-
types.type_from_id(t_id).unwrap(),
1585-
types.type_from_id(a2_id).unwrap()
1586-
));
1558+
assert!(std::ptr::eq(&types[t_id], &types[a1_id],));
1559+
assert!(std::ptr::eq(&types[t_id], &types[a2_id],));
15871560

15881561
Ok(())
15891562
}

0 commit comments

Comments
 (0)