A runtime bug was introduced when loading an assembly that contains a cyclic datastructure. The following code is valid Mun code because Foo is garbage collected type (even though its impossible to create this type at runtime).
pub struct Foo {
foo: Foo
}
When loading a munlib at runtime that contains this type the runtime hangs. This is due to the code in assembly.rs:
|
// Load all types |
|
while let Some(type_info) = types_to_load.pop_front() { |
|
match TypeInfo::try_from_abi(type_info, &type_table) { |
|
Ok(type_info) => { |
|
assert!(type_table.insert_type(Arc::new(type_info)).is_none()) |
|
} |
|
Err(TryFromAbiError::UnknownTypeId(_)) => types_to_load.push_back(type_info), |
|
} |
|
} |
When loading the type Foo, if the type Foo is not yet in the TypeTable loading the above snippet will fail.
We could do something by first creating the Arc<TypeInfo> and then injecting it somehow but it raises another interesting question. By storing the Arc<TypeInfo> in the field, we create a cycle. However, storing the type of a field as a Weak<TypeInfo> is also not an option in a case like this:
pub struct Foo {
bar: Bar
}
pub struct Bar {
foo: Foo
}
If in the case above we only hold an Arc<TypeInfo> of Bar, the type info of Foo might be dropped which is not what we want.
I see two approaches in solving this:
- Always retain all the TypeInfos ever allocated. Memory will grow over time, but I doubt it will become a major issue.
- Garbage collect TypeInfos.
The first option is definitely the easiest to implement, I recommend we first take that approach and optimize later. WDYT?
A runtime bug was introduced when loading an assembly that contains a cyclic datastructure. The following code is valid Mun code because
Foois garbage collected type (even though its impossible to create this type at runtime).When loading a munlib at runtime that contains this type the runtime hangs. This is due to the code in assembly.rs:
mun/crates/mun_runtime/src/assembly.rs
Lines 215 to 223 in fa07c5c
When loading the type
Foo, if the typeFoois not yet in theTypeTableloading the above snippet will fail.We could do something by first creating the
Arc<TypeInfo>and then injecting it somehow but it raises another interesting question. By storing theArc<TypeInfo>in the field, we create a cycle. However, storing the type of a field as aWeak<TypeInfo>is also not an option in a case like this:If in the case above we only hold an
Arc<TypeInfo>ofBar, the type info ofFoomight be dropped which is not what we want.I see two approaches in solving this:
The first option is definitely the easiest to implement, I recommend we first take that approach and optimize later. WDYT?