Skip to content

Commit 78a089b

Browse files
committed
use a single table per instance for resources, waitables, etc.
Per WebAssembly/component-model#513, the spec now puts resources, waitables, waitable sets, subtasks, and error contexts in the same table per instance. This updates the implementation to match. - Combine the `ResourceTable` and `StateTable` data structures into a single `HandleTable` structure - Rename `ComponentInstance::instance_resource_tables` to `instance_handle_tables` - Remove `ConcurrentState::waitable_tables` and `error_context_tables` in favor of the above - Move various associated functions from `ConcurrentState` to `ComponentInstance` so they can access `instance_resource_tables` While I was doing table-related things, I also updated `concurrent::Table::new` to reserve the zero handle to mean "invalid". This won't affect what the guest sees in any way, but it allows us to use `TableId::new(0)` to invalidate host-owned handles in e.g. `{Stream,Future}{Reader,Writer}::close`. Fixes #11189 Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 0a074af commit 78a089b

11 files changed

Lines changed: 1115 additions & 1130 deletions

File tree

crates/wasmtime/src/runtime/component/concurrent.rs

Lines changed: 306 additions & 333 deletions
Large diffs are not rendered by default.

crates/wasmtime/src/runtime/component/concurrent/error_contexts.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
/// Error context reference count local to a given (sub)component
2-
///
3-
/// This reference count is localized to a single (sub)component,
4-
/// rather than the global cross-component count (i.e. that determines
5-
/// when a error context can be completely removed)
6-
#[repr(transparent)]
7-
pub struct LocalErrorContextRefCount(pub(crate) usize);
8-
91
/// Error context reference count across a [`ComponentInstance`]
102
///
113
/// Contrasted to `LocalErrorContextRefCount`, this count is maintained

crates/wasmtime/src/runtime/component/concurrent/futures_and_streams.rs

Lines changed: 472 additions & 467 deletions
Large diffs are not rendered by default.

crates/wasmtime/src/runtime/component/concurrent/states.rs

Lines changed: 0 additions & 143 deletions
This file was deleted.

crates/wasmtime/src/runtime/component/concurrent/table.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,16 @@ impl TableEntry {
172172
impl Table {
173173
/// Create an empty table
174174
pub fn new() -> Self {
175-
Self {
175+
let mut me = Self {
176176
entries: Vec::new(),
177177
free_head: None,
178178
debug: false,
179-
}
179+
};
180+
181+
// Reserve 0 as an invalid entry.
182+
me.push(Tombstone).unwrap();
183+
184+
me
180185
}
181186

182187
/// Returns whether or not this table is empty.

crates/wasmtime/src/runtime/component/func/options.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::component::resources::{HostResourceData, HostResourceIndex, HostResou
33
use crate::component::{Instance, ResourceType};
44
use crate::prelude::*;
55
use crate::runtime::vm::component::{
6-
CallContexts, ComponentInstance, InstanceFlags, ResourceTable, ResourceTables,
6+
CallContexts, ComponentInstance, HandleTable, InstanceFlags, ResourceTables,
77
};
88
use crate::runtime::vm::{VMFuncRef, VMMemoryDefinition};
99
use crate::store::{StoreId, StoreOpaque};
@@ -473,7 +473,7 @@ pub struct LiftContext<'a> {
473473
instance: Pin<&'a mut ComponentInstance>,
474474
instance_handle: Instance,
475475

476-
host_table: &'a mut ResourceTable,
476+
host_table: &'a mut HandleTable,
477477
host_resource_data: &'a mut HostResourceData,
478478

479479
calls: &'a mut CallContexts,
@@ -490,7 +490,7 @@ impl<'a> LiftContext<'a> {
490490
) -> LiftContext<'a> {
491491
// From `&mut StoreOpaque` provided the goal here is to project out
492492
// three different disjoint fields owned by the store: memory,
493-
// `CallContexts`, and `ResourceTable`. There's no native API for that
493+
// `CallContexts`, and `HandleTable`. There's no native API for that
494494
// so it's hacked around a bit. This unsafe pointer cast could be fixed
495495
// with more methods in more places, but it doesn't seem worth doing it
496496
// at this time.

crates/wasmtime/src/runtime/store.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ pub struct StoreOpaque {
395395
/// and calls. These also interact with the `ResourceAny` type and its
396396
/// internal representation.
397397
#[cfg(feature = "component-model")]
398-
component_host_table: vm::component::ResourceTable,
398+
component_host_table: vm::component::HandleTable,
399399
#[cfg(feature = "component-model")]
400400
component_calls: vm::component::CallContexts,
401401
#[cfg(feature = "component-model")]
@@ -1957,7 +1957,7 @@ at https://bytecodealliance.org/security.
19571957
&mut self,
19581958
) -> (
19591959
&mut vm::component::CallContexts,
1960-
&mut vm::component::ResourceTable,
1960+
&mut vm::component::HandleTable,
19611961
&mut crate::component::HostResourceData,
19621962
) {
19631963
(
@@ -1984,7 +1984,7 @@ at https://bytecodealliance.org/security.
19841984
instance: crate::component::Instance,
19851985
) -> (
19861986
&mut vm::component::CallContexts,
1987-
&mut vm::component::ResourceTable,
1987+
&mut vm::component::HandleTable,
19881988
&mut crate::component::HostResourceData,
19891989
Pin<&mut vm::component::ComponentInstance>,
19901990
) {

crates/wasmtime/src/runtime/vm/component.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ use wasmtime_environ::{HostPtr, PrimaryMap, VMSharedTypeIndex};
3131
)]
3232
const INVALID_PTR: usize = 0xdead_dead_beef_beef_u64 as usize;
3333

34+
mod handle_table;
3435
mod libcalls;
3536
mod resources;
3637

38+
#[cfg(feature = "component-model-async")]
39+
pub use self::handle_table::{HandleKind, TransmitLocalState};
40+
pub use self::handle_table::{HandleTable, ResourceKind};
3741
#[cfg(feature = "component-model-async")]
3842
pub use self::resources::CallContext;
39-
pub use self::resources::{
40-
CallContexts, ResourceTable, ResourceTables, TypedResource, TypedResourceIndex,
41-
};
43+
pub use self::resources::{CallContexts, ResourceTables, TypedResource, TypedResourceIndex};
4244

4345
#[cfg(feature = "component-model-async")]
4446
use crate::component::concurrent;
@@ -78,11 +80,13 @@ pub struct ComponentInstance {
7880
// of the component can be thrown away (theoretically).
7981
component: Component,
8082

81-
/// State of resources for this component.
83+
/// State of handles (e.g. resources, waitables, etc.) for this component.
8284
///
83-
/// This is paired with other information to create a `ResourceTables` which
84-
/// is how this field is manipulated.
85-
instance_resource_tables: PrimaryMap<RuntimeComponentInstanceIndex, ResourceTable>,
85+
/// For resource handles, this is paired with other information to create a
86+
/// `ResourceTables` and manipulated through that. For other handles, this
87+
/// is used directly to translate guest handles to host representations and
88+
/// vice-versa.
89+
instance_handle_tables: PrimaryMap<RuntimeComponentInstanceIndex, HandleTable>,
8690

8791
/// State related to async for this component, e.g. futures, streams, tasks,
8892
/// etc.
@@ -273,16 +277,16 @@ impl ComponentInstance {
273277
) -> OwnedComponentInstance {
274278
let offsets = VMComponentOffsets::new(HostPtr, component.env_component());
275279
let num_instances = component.env_component().num_runtime_component_instances;
276-
let mut instance_resource_tables =
280+
let mut instance_handle_tables =
277281
PrimaryMap::with_capacity(num_instances.try_into().unwrap());
278282
for _ in 0..num_instances {
279-
instance_resource_tables.push(ResourceTable::default());
283+
instance_handle_tables.push(HandleTable::default());
280284
}
281285

282286
let mut ret = OwnedInstance::new(ComponentInstance {
283287
id,
284288
offsets,
285-
instance_resource_tables,
289+
instance_handle_tables,
286290
instances: PrimaryMap::with_capacity(
287291
component
288292
.env_component()
@@ -734,14 +738,14 @@ impl ComponentInstance {
734738
pub fn guest_tables(
735739
self: Pin<&mut Self>,
736740
) -> (
737-
&mut PrimaryMap<RuntimeComponentInstanceIndex, ResourceTable>,
741+
&mut PrimaryMap<RuntimeComponentInstanceIndex, HandleTable>,
738742
&ComponentTypes,
739743
) {
740744
// safety: we've chosen the `pin` guarantee of `self` to not apply to
741745
// the map returned.
742746
unsafe {
743747
let me = self.get_unchecked_mut();
744-
(&mut me.instance_resource_tables, me.component.types())
748+
(&mut me.instance_handle_tables, me.component.types())
745749
}
746750
}
747751

0 commit comments

Comments
 (0)