Skip to content

Commit e2cfe7b

Browse files
committed
Remove de-duplicative behavior of borrows in canon lower
1 parent 1eb69c1 commit e2cfe7b

File tree

2 files changed

+9
-45
lines changed

2 files changed

+9
-45
lines changed

design/mvp/CanonicalABI.md

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -264,26 +264,15 @@ The `Resource` class represents a runtime instance of a resource type:
264264
class Resource:
265265
t: ResourceType
266266
rep: int
267-
borrowers: MutableMapping[ComponentInstance, int]
268267

269268
def __init__(self, t, rep):
270269
self.t = t
271270
self.rep = rep
272-
self.borrowers = {}
273271
```
274272
The `t` field points to the [`resourcetype`](Explainer.md#type-definitions)
275273
used to create this `Resource` and is used to perform dynamic type checking
276-
below. Next, `rep` is the core representation of this `Resource` which is
277-
currently fixed to `i32` as described in the Explainer. Lastly, `borrowers` is
278-
a list of component instances that currently hold a `borrow` handle along with
279-
the index of this `borrow` handle in the `HandleTable`. This map is used to
280-
deduplicate `borrow` handles, preserving the invariant that a component
281-
instance contains *at most one* handle referring to a particular `Resource`.
282-
While the map here is a Python dictionary, using static analysis of the flow of
283-
resource types throughout a component instance DAG, an AOT compiler can
284-
alternatively implement `borrowers` with a fixed-size array embedded directly
285-
in the resource, assigning a static index to each potential client instance in
286-
the DAG.
274+
below. The `rep` field stores the representation value of this `Resource` whose
275+
type is currently fixed to `i32` as described in the Explainer.
287276

288277
The `OwnHandle` and `BorrowHandle` classes represent runtime handle values of
289278
`own` and `borrow` type, resp:
@@ -353,35 +342,25 @@ class HandleTable:
353342
self.free = []
354343

355344
def insert(self, cx, h):
356-
match h:
357-
case OwnHandle():
358-
assert(len(h.resource.borrowers) == 0)
359-
case BorrowHandle():
360-
if cx.inst in h.resource.borrowers:
361-
return h.resource.borrowers[cx.inst]
362-
363345
if self.free:
364346
i = self.free.pop()
365347
assert(self.array[i] is None)
366348
self.array[i] = h
367349
else:
368350
i = len(self.array)
369351
self.array.append(h)
370-
371352
if isinstance(h, BorrowHandle):
372-
h.resource.borrowers[cx.inst] = i
373353
cx.call.borrow_count += 1
374354
return i
375355
```
376356
The `HandleTable` class maintains a dense array of handles that can contain
377-
holes created by the `remove` method (defined below). These holes are kept
378-
in a separate Python list here, but an optimizing implementation could instead
379-
store the free list in the free elements of `array`. When inserting a new
380-
handle, `HandleTable` first consults the `free` list, which is popped LIFO to
381-
better detect use-after-free bugs in the guest code. The `insert` method
382-
uses the `Handle.borrowers` map to deduplicate borrowed handles. For
383-
non-deduplicated handles, `insert` increments `Call.borrow_count` to guard that
384-
this handle has been dropped by the end of the call.
357+
holes created by the `remove` method (defined below). These holes are kept in a
358+
separate Python list here, but an optimizing implementation could instead store
359+
the free list in the free elements of `array`. When inserting a new handle,
360+
`HandleTable` first consults the `free` list, which is popped LIFO to better
361+
detect use-after-free bugs in the guest code. The `insert` method increments
362+
`Call.borrow_count` to guard that this handle has been dropped by the end of
363+
the call.
385364

386365
The `get` method is used by other `HandleTable` methods and canonical
387366
definitions below and uses dynamic guards to catch out-of-bounds and
@@ -418,11 +397,9 @@ for later recycling by `insert` (above).
418397
match t:
419398
case Own(_):
420399
trap_if(not isinstance(h, OwnHandle))
421-
assert(len(h.resource.borrowers) == 0)
422400
case Borrow(_):
423401
trap_if(not isinstance(h, BorrowHandle))
424402
cx.call.borrow_count -= 1
425-
del h.resource.borrowers[cx.inst]
426403
self.array[i] = None
427404
self.free.append(i)
428405
return h

design/mvp/canonical-abi/definitions.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,10 @@ def __init__(self):
316316
class Resource:
317317
t: ResourceType
318318
rep: int
319-
borrowers: MutableMapping[ComponentInstance, int]
320319

321320
def __init__(self, t, rep):
322321
self.t = t
323322
self.rep = rep
324-
self.borrowers = {}
325323

326324
#
327325

@@ -365,23 +363,14 @@ def __init__(self):
365363
self.free = []
366364

367365
def insert(self, cx, h):
368-
match h:
369-
case OwnHandle():
370-
assert(len(h.resource.borrowers) == 0)
371-
case BorrowHandle():
372-
if cx.inst in h.resource.borrowers:
373-
return h.resource.borrowers[cx.inst]
374-
375366
if self.free:
376367
i = self.free.pop()
377368
assert(self.array[i] is None)
378369
self.array[i] = h
379370
else:
380371
i = len(self.array)
381372
self.array.append(h)
382-
383373
if isinstance(h, BorrowHandle):
384-
h.resource.borrowers[cx.inst] = i
385374
cx.call.borrow_count += 1
386375
return i
387376

@@ -409,11 +398,9 @@ def remove(self, cx, i, t):
409398
match t:
410399
case Own(_):
411400
trap_if(not isinstance(h, OwnHandle))
412-
assert(len(h.resource.borrowers) == 0)
413401
case Borrow(_):
414402
trap_if(not isinstance(h, BorrowHandle))
415403
cx.call.borrow_count -= 1
416-
del h.resource.borrowers[cx.inst]
417404
self.array[i] = None
418405
self.free.append(i)
419406
return h

0 commit comments

Comments
 (0)