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