Skip to content

Commit 317e475

Browse files
authored
Change stream/future built-ins' typeidx to refer to full stream/future type (#512)
1 parent 57510bc commit 317e475

File tree

4 files changed

+230
-220
lines changed

4 files changed

+230
-220
lines changed

design/mvp/CanonicalABI.md

Lines changed: 63 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,11 +3664,12 @@ async def canon_subtask_drop(task, i):
36643664

36653665
For canonical definitions:
36663666
```wat
3667-
(canon stream.new $t (core func $f))
3668-
(canon future.new $t (core func $f))
3667+
(canon stream.new $stream_t (core func $f))
3668+
(canon future.new $future_t (core func $f))
36693669
```
36703670
validation specifies:
36713671
* `$f` is given type `(func (result i64))`
3672+
* `$stream_t`/`$future_t` is a type of the form `(stream $t?)`/`(future $t?)`
36723673

36733674
Calling `$f` calls `canon_{stream,future}_new` which adds two elements to the
36743675
current component instance's `waitables` table and returns the indices packed
@@ -3679,16 +3680,16 @@ the readable end is subsequently transferred to another component (or the host)
36793680
via `stream` or `future` parameter/result type (see `lift_{stream,future}`
36803681
above).
36813682
```python
3682-
async def canon_stream_new(elem_type, task):
3683+
async def canon_stream_new(stream_t, task):
36833684
trap_if(not task.inst.may_leave)
3684-
stream = ReadableStreamGuestImpl(elem_type)
3685+
stream = ReadableStreamGuestImpl(stream_t.t)
36853686
ri = task.inst.waitables.add(ReadableStreamEnd(stream))
36863687
wi = task.inst.waitables.add(WritableStreamEnd(stream))
36873688
return [ ri | (wi << 32) ]
36883689

3689-
async def canon_future_new(t, task):
3690+
async def canon_future_new(future_t, task):
36903691
trap_if(not task.inst.may_leave)
3691-
future = ReadableStreamGuestImpl(t)
3692+
future = ReadableStreamGuestImpl(future_t.t)
36923693
ri = task.inst.waitables.add(ReadableFutureEnd(future))
36933694
wi = task.inst.waitables.add(WritableFutureEnd(future))
36943695
return [ ri | (wi << 32) ]
@@ -3703,45 +3704,49 @@ the future built-ins below.
37033704

37043705
For canonical definitions:
37053706
```wat
3706-
(canon stream.read $t $opts (core func $f))
3707-
(canon stream.write $t $opts (core func $f))
3707+
(canon stream.read $stream_t $opts (core func $f))
3708+
(canon stream.write $stream_t $opts (core func $f))
37083709
```
37093710
In addition to [general validation of `$opts`](#canonopt-validation) validation
37103711
specifies:
37113712
* `$f` is given type `(func (param i32 i32 i32) (result i32))`
3712-
* [`lower($t)` above](#canonopt-validation) defines required options for `stream.write`
3713-
* [`lift($t)` above](#canonopt-validation) defines required options for `stream.read`
3714-
* `memory` is required to be present
3713+
* `$stream_t` is a type of the form `(stream $t?)`
3714+
* If `$t` is present:
3715+
* [`lower($t)` above](#canonopt-validation) defines required options for `stream.write`
3716+
* [`lift($t)` above](#canonopt-validation) defines required options for `stream.read`
3717+
* `memory` is required to be present
37153718

37163719
For canonical definitions:
37173720
```wat
3718-
(canon future.read $t $opts (core func $f))
3719-
(canon future.write $t $opts (core func $f))
3721+
(canon future.read $future_t $opts (core func $f))
3722+
(canon future.write $future_t $opts (core func $f))
37203723
```
37213724
validation specifies:
37223725
* `$f` is given type `(func (param i32 i32) (result i32))`
3723-
* [`lower($t)` above](#canonopt-validation) defines required options for `future.write`
3724-
* [`lift($t)` above](#canonopt-validation) defines required options for `future.read`
3725-
* `memory` is required to be present
3726+
* `$future_t` is a type of the form `(future $t?)`
3727+
* If `$t` is present:
3728+
* [`lower($t)` above](#canonopt-validation) defines required options for `future.write`
3729+
* [`lift($t)` above](#canonopt-validation) defines required options for `future.read`
3730+
* `memory` is required to be present
37263731

37273732
The implementation of these four built-ins all funnel down to a single
37283733
parameterized `copy` function:
37293734
```python
3730-
async def canon_stream_read(t, opts, task, i, ptr, n):
3735+
async def canon_stream_read(stream_t, opts, task, i, ptr, n):
37313736
return await copy(ReadableStreamEnd, WritableBufferGuestImpl, EventCode.STREAM_READ,
3732-
t, opts, task, i, ptr, n)
3737+
stream_t, opts, task, i, ptr, n)
37333738

3734-
async def canon_stream_write(t, opts, task, i, ptr, n):
3739+
async def canon_stream_write(stream_t, opts, task, i, ptr, n):
37353740
return await copy(WritableStreamEnd, ReadableBufferGuestImpl, EventCode.STREAM_WRITE,
3736-
t, opts, task, i, ptr, n)
3741+
stream_t, opts, task, i, ptr, n)
37373742

3738-
async def canon_future_read(t, opts, task, i, ptr):
3743+
async def canon_future_read(future_t, opts, task, i, ptr):
37393744
return await copy(ReadableFutureEnd, WritableBufferGuestImpl, EventCode.FUTURE_READ,
3740-
t, opts, task, i, ptr, 1)
3745+
future_t, opts, task, i, ptr, 1)
37413746

3742-
async def canon_future_write(t, opts, task, i, ptr):
3747+
async def canon_future_write(future_t, opts, task, i, ptr):
37433748
return await copy(WritableFutureEnd, ReadableBufferGuestImpl, EventCode.FUTURE_WRITE,
3744-
t, opts, task, i, ptr, 1)
3749+
future_t, opts, task, i, ptr, 1)
37453750
```
37463751

37473752
Introducing the `copy` function in chunks, `copy` first checks that the
@@ -3751,15 +3756,15 @@ finite number of pipelined reads or writes.) Then a readable or writable buffer
37513756
is created which (in `Buffer`'s constructor) eagerly checks the alignment and
37523757
bounds of (`i`, `n`).
37533758
```python
3754-
async def copy(EndT, BufferT, event_code, t, opts, task, i, ptr, n):
3759+
async def copy(EndT, BufferT, event_code, stream_or_future_t, opts, task, i, ptr, n):
37553760
trap_if(not task.inst.may_leave)
37563761
e = task.inst.waitables.get(i)
37573762
trap_if(not isinstance(e, EndT))
3758-
trap_if(e.stream.t != t)
3763+
trap_if(e.stream.t != stream_or_future_t.t)
37593764
trap_if(e.copying)
3760-
assert(not contains_borrow(t))
3765+
assert(not contains_borrow(stream_or_future_t))
37613766
cx = LiftLowerContext(opts, task.inst, borrow_scope = None)
3762-
buffer = BufferT(t, cx, ptr, n)
3767+
buffer = BufferT(stream_or_future_t.t, cx, ptr, n)
37633768
```
37643769

37653770
Next, in the synchronous case, `Task.wait_on` is used to synchronously and
@@ -3841,35 +3846,36 @@ the `read` or `write` and so this number is packed into the `i32` result.
38413846

38423847
For canonical definitions:
38433848
```wat
3844-
(canon stream.cancel-read $t $async? (core func $f))
3845-
(canon stream.cancel-write $t $async? (core func $f))
3846-
(canon future.cancel-read $t $async? (core func $f))
3847-
(canon future.cancel-write $t $async? (core func $f))
3849+
(canon stream.cancel-read $stream_t $async? (core func $f))
3850+
(canon stream.cancel-write $stream_t $async? (core func $f))
3851+
(canon future.cancel-read $future_t $async? (core func $f))
3852+
(canon future.cancel-write $future_t $async? (core func $f))
38483853
```
38493854
validation specifies:
38503855
* `$f` is given type `(func (param i32) (result i32))`
3856+
* `$stream_t`/`$future_t` is a type of the form `(stream $t?)`/`(future $t?)`
38513857
* 🚝 - `async` is allowed (otherwise it must be `false`)
38523858

38533859
The implementation of these four built-ins all funnel down to a single
38543860
parameterized `cancel_copy` function:
38553861
```python
3856-
async def canon_stream_cancel_read(t, sync, task, i):
3857-
return await cancel_copy(ReadableStreamEnd, EventCode.STREAM_READ, t, sync, task, i)
3862+
async def canon_stream_cancel_read(stream_t, sync, task, i):
3863+
return await cancel_copy(ReadableStreamEnd, EventCode.STREAM_READ, stream_t, sync, task, i)
38583864

3859-
async def canon_stream_cancel_write(t, sync, task, i):
3860-
return await cancel_copy(WritableStreamEnd, EventCode.STREAM_WRITE, t, sync, task, i)
3865+
async def canon_stream_cancel_write(stream_t, sync, task, i):
3866+
return await cancel_copy(WritableStreamEnd, EventCode.STREAM_WRITE, stream_t, sync, task, i)
38613867

3862-
async def canon_future_cancel_read(t, sync, task, i):
3863-
return await cancel_copy(ReadableFutureEnd, EventCode.FUTURE_READ, t, sync, task, i)
3868+
async def canon_future_cancel_read(future_t, sync, task, i):
3869+
return await cancel_copy(ReadableFutureEnd, EventCode.FUTURE_READ, future_t, sync, task, i)
38643870

3865-
async def canon_future_cancel_write(t, sync, task, i):
3866-
return await cancel_copy(WritableFutureEnd, EventCode.FUTURE_WRITE, t, sync, task, i)
3871+
async def canon_future_cancel_write(future_t, sync, task, i):
3872+
return await cancel_copy(WritableFutureEnd, EventCode.FUTURE_WRITE, future_t, sync, task, i)
38673873

3868-
async def cancel_copy(EndT, event_code, t, sync, task, i):
3874+
async def cancel_copy(EndT, event_code, stream_or_future_t, sync, task, i):
38693875
trap_if(not task.inst.may_leave)
38703876
e = task.inst.waitables.get(i)
38713877
trap_if(not isinstance(e, EndT))
3872-
trap_if(e.stream.t != t)
3878+
trap_if(e.stream.t != stream_or_future_t.t)
38733879
trap_if(not e.copying)
38743880
if not e.has_pending_event():
38753881
e.stream.cancel()
@@ -3908,36 +3914,37 @@ caller can assume that ownership of the buffer has been returned.
39083914

39093915
For canonical definitions:
39103916
```wat
3911-
(canon stream.close-readable $t (core func $f))
3912-
(canon stream.close-writable $t (core func $f))
3913-
(canon future.close-readable $t (core func $f))
3914-
(canon future.close-writable $t (core func $f))
3917+
(canon stream.close-readable $stream_t (core func $f))
3918+
(canon stream.close-writable $stream_t (core func $f))
3919+
(canon future.close-readable $future_t (core func $f))
3920+
(canon future.close-writable $future_t (core func $f))
39153921
```
39163922
validation specifies:
39173923
* `$f` is given type `(func (param i32 i32))`
3924+
* `$stream_t`/`$future_t` is a type of the form `(stream $t?)`/`(future $t?)`
39183925

39193926
Calling `$f` removes the readable or writable end of the stream or future at
39203927
the given index from the current component instance's `waitable` table,
39213928
performing the guards and bookkeeping defined by
39223929
`{Readable,Writable}{Stream,Future}End.drop()` above.
39233930
```python
3924-
async def canon_stream_close_readable(t, task, i):
3925-
return await close(ReadableStreamEnd, t, task, i)
3931+
async def canon_stream_close_readable(stream_t, task, i):
3932+
return await close(ReadableStreamEnd, stream_t, task, i)
39263933

3927-
async def canon_stream_close_writable(t, task, hi):
3928-
return await close(WritableStreamEnd, t, task, hi)
3934+
async def canon_stream_close_writable(stream_t, task, hi):
3935+
return await close(WritableStreamEnd, stream_t, task, hi)
39293936

3930-
async def canon_future_close_readable(t, task, i):
3931-
return await close(ReadableFutureEnd, t, task, i)
3937+
async def canon_future_close_readable(future_t, task, i):
3938+
return await close(ReadableFutureEnd, future_t, task, i)
39323939

3933-
async def canon_future_close_writable(t, task, hi):
3934-
return await close(WritableFutureEnd, t, task, hi)
3940+
async def canon_future_close_writable(future_t, task, hi):
3941+
return await close(WritableFutureEnd, future_t, task, hi)
39353942

3936-
async def close(EndT, t, task, hi):
3943+
async def close(EndT, stream_or_future_t, task, hi):
39373944
trap_if(not task.inst.may_leave)
39383945
e = task.inst.waitables.remove(hi)
39393946
trap_if(not isinstance(e, EndT))
3940-
trap_if(e.stream.t != t)
3947+
trap_if(e.stream.t != stream_or_future_t.t)
39413948
e.drop()
39423949
return []
39433950
```

0 commit comments

Comments
 (0)