@@ -1866,12 +1866,14 @@ def lower_heap_values(cx, vs, ts, out_param):
1866
1866
tuple_value = {str (i): v for i,v in enumerate (vs)}
1867
1867
if out_param is None :
1868
1868
ptr = cx.opts.realloc(0 , 0 , alignment(tuple_type), elem_size(tuple_type))
1869
+ flat_vals = [ptr]
1869
1870
else :
1870
1871
ptr = out_param.next(' i32' )
1872
+ flat_vals = []
1871
1873
trap_if(ptr != align_to(ptr, alignment(tuple_type)))
1872
1874
trap_if(ptr + elem_size(tuple_type) > len (cx.opts.memory))
1873
1875
store(cx, tuple_value, tuple_type, ptr)
1874
- return [ptr]
1876
+ return flat_vals
1875
1877
```
1876
1878
The ` may_leave ` flag is guarded by ` canon_lower ` below to prevent a component
1877
1879
from calling out of the component while in the middle of lowering, ensuring
@@ -2205,43 +2207,61 @@ component instance defining a resource can access its representation.
2205
2207
2206
2208
For a canonical definition:
2207
2209
``` wasm
2208
- (canon task.start (core func $f))
2210
+ (canon task.start $ft (core func $f))
2209
2211
```
2210
2212
validation specifies:
2211
- * ` $f ` is given type ` (func (param i32)) `
2213
+ * ` $f ` is given type ` $ft ` , which validation requires to be a (core) function type
2212
2214
2213
2215
Calling ` $f ` invokes the following function which extracts the arguments from the
2214
2216
caller and lowers them into the current instance:
2215
2217
``` python
2216
- async def canon_task_start (task , i ):
2218
+ async def canon_task_start (task , core_ft , flat_args ):
2219
+ assert (len (core_ft.params) == len (flat_args))
2217
2220
trap_if(task.opts.sync)
2221
+ trap_if(core_ft != flatten_functype(CanonicalOptions(), FuncType([], task.ft.params), ' lower' ))
2218
2222
task.start()
2219
- lower_async_values(task, task.start_thunk(), task.ft.param_types(), CoreValueIter([i]))
2220
- return []
2223
+ args = task.start_thunk()
2224
+ flat_results = lower_sync_values(task, MAX_FLAT_RESULTS , args, task.ft.param_types(), CoreValueIter(flat_args))
2225
+ assert (len (core_ft.results) == len (flat_results))
2226
+ return flat_results
2221
2227
```
2222
- The call to the ` Task.start ` (defined above) ensures that ` canon task.start ` is
2223
- called exactly once, before ` canon task.return ` , before an async call finishes.
2228
+ An expected implementation of ` task.start ` would generate a core wasm function
2229
+ for each lowering of an ` async ` -lifted export that performs the fused copy of
2230
+ the arguments into the caller, storing the index of this function in the ` Task `
2231
+ structure and using ` call_indirect ` to perform the function-type-equality check
2232
+ required here. The call to ` Task.start ` (defined above) ensures that `canon
2233
+ task.start` is called exactly once, before ` canon task.return`, before an async
2234
+ call finishes.
2224
2235
2225
2236
### 🔀 ` canon task.return `
2226
2237
2227
2238
For a canonical definition:
2228
2239
``` wasm
2229
- (canon task.return (core func $f))
2240
+ (canon task.return $ft (core func $f))
2230
2241
```
2231
2242
validation specifies:
2232
- * ` $f ` is given type ` (func (param i32)) `
2243
+ * ` $f ` is given type ` $ft ` , which validation requires to be a (core) function type
2233
2244
2234
2245
Calling ` $f ` invokes the following function which lifts the results from the
2235
2246
current instance and passes them to the caller:
2236
2247
``` python
2237
- async def canon_task_return (task , i ):
2248
+ async def canon_task_return (task , core_ft , flat_args ):
2249
+ assert (len (core_ft.params) == len (flat_args))
2238
2250
trap_if(task.opts.sync)
2251
+ trap_if(core_ft != flatten_functype(CanonicalOptions(), FuncType(task.ft.results, []), ' lower' ))
2239
2252
task.return_()
2240
- task.return_thunk(lift_async_values(task, CoreValueIter([i]), task.ft.result_types()))
2253
+ results = lift_sync_values(task, MAX_FLAT_PARAMS , CoreValueIter(flat_args), task.ft.result_types())
2254
+ task.return_thunk(results)
2255
+ assert (len (core_ft.results) == 0 )
2241
2256
return []
2242
2257
```
2243
- The call to ` Task.return_ ` (defined above) ensures that ` canon task.return ` is
2244
- called exactly once, after ` canon task.start ` , before an async call finishes.
2258
+ An expected implementation of ` task.return ` would generate a core wasm function
2259
+ for each lowering of an ` async ` -lifted export that performs the fused copy of
2260
+ the results into the caller, storing the index of this function in the ` Task `
2261
+ structure and using ` call_indirect ` to perform the function-type-equality check
2262
+ required here. The call to ` Task.return_ ` (defined above) ensures that `canon
2263
+ task.return` is called exactly once, after ` canon task.start`, before an async
2264
+ call finishes.
2245
2265
2246
2266
### 🔀 ` canon task.wait `
2247
2267
0 commit comments