@@ -12,6 +12,7 @@ being specified here.
1212 * [Canonical ABI Options](#canonical-abi-options)
1313 * [Runtime State](#runtime-state)
1414 * [Component Instance State](#component-instance-state)
15+ * [Table State](#table-state)
1516 * [Resource State](#resource-state)
1617 * [Task State](#task-state)
1718 * [Buffer, Stream and Future State](#buffer-stream-and-future-state)
@@ -172,60 +173,12 @@ class ComponentInstance:
172173 self.starting_pending_task = False
173174```
174175
176+ #### Table State
175177
176- #### Resource State
177-
178- The `ResourceTables` stored in the `resources` field maps `ResourceType`s to
179- `Table`s of `ResourceHandle`s (defined next), establishing a separate
180- `i32`-indexed array per resource type:
181- ```python
182- class ResourceTables:
183- rt_to_table: MutableMapping[ResourceType, Table[ResourceHandle]]
184-
185- def __init__(self):
186- self.rt_to_table = dict()
187-
188- def table(self, rt):
189- if rt not in self.rt_to_table:
190- self.rt_to_table[rt] = Table[ResourceHandle]()
191- return self.rt_to_table[rt]
192-
193- def get(self, rt, i):
194- return self.table(rt).get(i)
195- def add(self, rt, h):
196- return self.table(rt).add(h)
197- def remove(self, rt, i):
198- return self.table(rt).remove(i)
199- ```
200- While this Python code performs a dynamic hash-table lookup on each handle
201- table access, as we'll see below, the `rt` parameter is always statically known
202- such that a normal implementation can statically enumerate all `Table` objects
203- at compile time and then route the calls to `get`, `add` and `remove` to the
204- correct `Table` at the callsite. The net result is that each component instance
205- will contain one handle table per resource type used by the component, with
206- each compiled adapter function accessing the correct handle table as-if it were
207- a global variable.
208-
209- The `ResourceType` class represents a concrete resource type that has been
210- created by the component instance `impl`. `ResourceType` objects are used as
211- keys by `ResourceTables` above and thus we assume that Python object identity
212- corresponds to resource type equality, as defined by [type checking] rules.
213- ```python
214- class ResourceType(Type):
215- impl: ComponentInstance
216- dtor: Optional[Callable]
217- dtor_sync: bool
218- dtor_callback: Optional[Callable]
219-
220- def __init__(self, impl, dtor = None, dtor_sync = True, dtor_callback = None):
221- self.impl = impl
222- self.dtor = dtor
223- self.dtor_sync = dtor_sync
224- self.dtor_callback = dtor_callback
225- ```
226- The `Table` class, used by `ResourceTables` above, encapsulates a single
227- mutable, growable array of generic elements, indexed by Core WebAssembly
228- `i32`s.
178+ The generic `Table` class, used by the `resources`, `waitables` and
179+ `error_contexts` fields of `ComponentInstance` above, encapsulates a single
180+ mutable, growable array of elements that are represented in Core WebAssembly as
181+ `i32` indices into the array.
229182```python
230183ElemT = TypeVar('ElemT')
231184class Table(Generic[ElemT]):
@@ -277,6 +230,40 @@ The limit of `2**30` ensures that the high 2 bits of table indices are unset
277230and available for other use in guest code (e.g., for tagging, packed words or
278231sentinel values).
279232
233+
234+ #### Resource State
235+
236+ The `ResourceTables` stored in the `resources` field maps `ResourceType`s to
237+ `Table`s of `ResourceHandle`s (defined next), establishing a separate
238+ `i32`-indexed array per resource type:
239+ ```python
240+ class ResourceTables:
241+ rt_to_table: MutableMapping[ResourceType, Table[ResourceHandle]]
242+
243+ def __init__(self):
244+ self.rt_to_table = dict()
245+
246+ def table(self, rt):
247+ if rt not in self.rt_to_table:
248+ self.rt_to_table[rt] = Table[ResourceHandle]()
249+ return self.rt_to_table[rt]
250+
251+ def get(self, rt, i):
252+ return self.table(rt).get(i)
253+ def add(self, rt, h):
254+ return self.table(rt).add(h)
255+ def remove(self, rt, i):
256+ return self.table(rt).remove(i)
257+ ```
258+ While this Python code performs a dynamic hash-table lookup on each handle
259+ table access, as we'll see below, the `rt` parameter is always statically known
260+ such that a normal implementation can statically enumerate all `Table` objects
261+ at compile time and then route the calls to `get`, `add` and `remove` to the
262+ correct `Table` at the callsite. The net result is that each component instance
263+ will contain one handle table per resource type used by the component, with
264+ each compiled adapter function accessing the correct handle table as-if it were
265+ a global variable.
266+
280267The `ResourceHandle` class defines the elements of the per-resource-type
281268`Table`s stored in `ResourceTables`:
282269```python
@@ -315,6 +302,24 @@ table only contains `own` or `borrow` handles and then, based on this,
315302statically eliminate the `own` and the `lend_count` xor `borrow_scope` fields,
316303and guards thereof.
317304
305+ The `ResourceType` class represents a concrete resource type that has been
306+ created by the component instance `impl`. `ResourceType` objects are used as
307+ keys by `ResourceTables` above and thus we assume that Python object identity
308+ corresponds to resource type equality, as defined by [type checking] rules.
309+ ```python
310+ class ResourceType(Type):
311+ impl: ComponentInstance
312+ dtor: Optional[Callable]
313+ dtor_sync: bool
314+ dtor_callback: Optional[Callable]
315+
316+ def __init__(self, impl, dtor = None, dtor_sync = True, dtor_callback = None):
317+ self.impl = impl
318+ self.dtor = dtor
319+ self.dtor_sync = dtor_sync
320+ self.dtor_callback = dtor_callback
321+ ```
322+
318323
319324#### Task State
320325
0 commit comments