Skip to content

Commit 6d44da5

Browse files
committed
Fix infinite recursion caused by aliased resources.
This commit fixes an existing bug exposed by the refactoring (likely due to the changes in the order in which nodes are processed for implicit arguments). Previously, an interface might contain a type alias for another resource it owns; this lead to the alias information of the resource being self-referential for the interface containing the aliased resource. It would then lead to infinite recursion in an attempt to remap such an interface when populating implicit instantiation arguments. The fix is to clear the self-referencing information while converting an interface during package parsing.
1 parent e77ae99 commit 6d44da5

5 files changed

Lines changed: 123 additions & 2 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package test:comp;
2+
3+
let x = new foo:bar { ... };
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(export (;0;) "fields" (type (sub resource)))
5+
(export (;1;) "headers" (type (eq 0)))
6+
)
7+
)
8+
(import "test:comp/types" (instance (;0;) (type 0)))
9+
(alias export 0 "fields" (type (;1;)))
10+
(type (;2;)
11+
(instance
12+
(alias outer 1 1 (type (;0;)))
13+
(export (;1;) "headers" (type (eq 0)))
14+
(type (;2;) (own 1))
15+
(type (;3;) (func (result 2)))
16+
(export (;0;) "get-headers" (func (type 3)))
17+
)
18+
)
19+
(import "test:comp/incoming-request" (instance (;1;) (type 2)))
20+
(type (;3;)
21+
(component
22+
(type (;0;)
23+
(instance
24+
(export (;0;) "fields" (type (sub resource)))
25+
(export (;1;) "headers" (type (eq 0)))
26+
)
27+
)
28+
(import "test:comp/types" (instance (;0;) (type 0)))
29+
(alias export 0 "fields" (type (;1;)))
30+
(type (;2;)
31+
(instance
32+
(alias outer 1 1 (type (;0;)))
33+
(export (;1;) "headers" (type (eq 0)))
34+
(type (;2;) (own 1))
35+
(type (;3;) (func (result 2)))
36+
(export (;0;) "get-headers" (func (type 3)))
37+
)
38+
)
39+
(import "test:comp/incoming-request" (instance (;1;) (type 2)))
40+
)
41+
)
42+
(import "unlocked-dep=<foo:bar>" (component (;0;) (type 3)))
43+
(instance $x (;2;) (instantiate 0
44+
(with "test:comp/types" (instance 0))
45+
(with "test:comp/incoming-request" (instance 1))
46+
)
47+
)
48+
(@producers
49+
(processed-by "wac-parser" "0.1.0")
50+
)
51+
)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(export (;0;) "fields" (type (sub resource)))
5+
(export (;1;) "headers" (type (eq 0)))
6+
)
7+
)
8+
(import "test:comp/types" (instance (;0;) (type 0)))
9+
(alias export 0 "headers" (type (;1;)))
10+
(type (;2;)
11+
(instance
12+
(alias outer 1 1 (type (;0;)))
13+
(export (;1;) "headers" (type (eq 0)))
14+
(type (;2;) (own 1))
15+
(type (;3;) (func (result 2)))
16+
(export (;0;) "get-headers" (func (type 3)))
17+
)
18+
)
19+
(import "test:comp/incoming-request" (instance (;1;) (type 2)))
20+
(core module (;0;)
21+
(type (;0;) (func (param i32)))
22+
(type (;1;) (func (result i32)))
23+
(type (;2;) (func (param i32 i32 i32 i32) (result i32)))
24+
(import "test:comp/types" "[resource-drop]fields" (func (;0;) (type 0)))
25+
(import "test:comp/incoming-request" "get-headers" (func (;1;) (type 1)))
26+
(func (;2;) (type 2) (param i32 i32 i32 i32) (result i32)
27+
unreachable
28+
)
29+
(memory (;0;) 0)
30+
(export "memory" (memory 0))
31+
(export "cabi_realloc" (func 2))
32+
(@producers
33+
(processed-by "wit-component" "0.203.0")
34+
)
35+
)
36+
(alias export 0 "fields" (type (;3;)))
37+
(core func (;0;) (canon resource.drop 3))
38+
(core instance (;0;)
39+
(export "[resource-drop]fields" (func 0))
40+
)
41+
(alias export 1 "get-headers" (func (;0;)))
42+
(core func (;1;) (canon lower (func 0)))
43+
(core instance (;1;)
44+
(export "get-headers" (func 1))
45+
)
46+
(core instance (;2;) (instantiate 0
47+
(with "test:comp/types" (instance 0))
48+
(with "test:comp/incoming-request" (instance 1))
49+
)
50+
)
51+
(alias core export 2 "memory" (core memory (;0;)))
52+
(alias core export 2 "cabi_realloc" (core func (;2;)))
53+
(@producers
54+
(processed-by "wit-component" "0.203.0")
55+
)
56+
)

crates/wac-types/src/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,9 @@ impl fmt::Display for FuncKind {
789789
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
790790
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
791791
pub struct ResourceAlias {
792-
/// The owning interface for the resource.
792+
/// The foreign owning interface for the resource.
793793
///
794-
/// This may be `None` if the resource is owned by a world.
794+
/// This may be `None` if the resource does not have a foreign interface owner.
795795
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
796796
pub owner: Option<InterfaceId>,
797797
/// The id of the resource that was aliased.

crates/wac-types/src/package.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,17 @@ impl<'a> TypeConverter<'a> {
551551
} = ty
552552
{
553553
self.use_or_own(Owner::Interface(id), name, *referenced, *created);
554+
555+
// Prevent self-referential ownership of any aliased resources in this interface
556+
if let ItemKind::Type(Type::Resource(res)) = export {
557+
if let Some(ResourceAlias { owner, .. }) = &mut self.types[res].alias {
558+
if let Some(owner_id) = owner {
559+
if *owner_id == id {
560+
*owner = None;
561+
}
562+
}
563+
}
564+
}
554565
}
555566

556567
let prev = self.types[id].exports.insert(name.clone(), export);

0 commit comments

Comments
 (0)