@@ -1525,35 +1525,39 @@ MAX_FLAT_PARAMS = 16
1525
1525
MAX_FLAT_RESULTS = 1
1526
1526
1527
1527
def flatten_functype (opts , ft , context ):
1528
+ flat_params = flatten_types(ft.param_types())
1529
+ flat_results = flatten_types(ft.result_types())
1528
1530
if opts.sync:
1529
- flat_params = flatten_types(ft.param_types())
1530
1531
if len (flat_params) > MAX_FLAT_PARAMS :
1531
1532
flat_params = [' i32' ]
1532
-
1533
- flat_results = flatten_types(ft.result_types())
1534
1533
if len (flat_results) > MAX_FLAT_RESULTS :
1535
1534
match context:
1536
1535
case ' lift' :
1537
1536
flat_results = [' i32' ]
1538
1537
case ' lower' :
1539
1538
flat_params += [' i32' ]
1540
1539
flat_results = []
1541
-
1542
1540
return CoreFuncType(flat_params, flat_results)
1543
1541
else :
1544
1542
match context:
1545
1543
case ' lift' :
1546
1544
flat_params = []
1547
1545
flat_results = []
1548
1546
case ' lower' :
1549
- flat_params = [' i32' , ' i32' ]
1547
+ if len (flat_params) > 1 :
1548
+ flat_params = [' i32' ]
1549
+ if len (flat_results) > 0 :
1550
+ flat_params += [' i32' ]
1550
1551
flat_results = [' i32' ]
1551
1552
return CoreFuncType(flat_params, flat_results)
1552
1553
1553
1554
def flatten_types (ts ):
1554
1555
return [ft for t in ts for ft in flatten_type(t)]
1555
1556
```
1556
- As shown here, the core signatures ` async ` functions are fixed and don't vary
1557
+ As shown here, the core signatures ` async ` functions use a lower limit on the
1558
+ maximum number of parameters (1) and results (0) passed as scalars before
1559
+ falling back to passing through memory.
1560
+
1557
1561
based on the function type (parameters and results are passed through memory
1558
1562
pointed to by the fixed ` i32 ` parameters).
1559
1563
@@ -1859,32 +1863,17 @@ def lower_flat_flags(v, labels):
1859
1863
1860
1864
### Lifting and Lowering Values
1861
1865
1862
- The ` lift_(sync|async)_values ` functions define how to lift a list of core
1863
- parameters or results (given by the ` CoreValueIter ` ` vi ` ) into a tuple of
1864
- component-level values with types ` ts ` . The sync and async variants differ in
1865
- how much they can pass in scalar "registers" before falling back to passing
1866
- values through linear memory: sync functions use up to ` max_flat ` scalars
1867
- whereas async functions have a single fixed ` i32 ` that is either a single
1868
- scalar value or a pointer into linear memory:
1866
+ The ` lift_flat_values ` function defines how to lift a list of core
1867
+ parameters or results (given by the ` CoreValueIter ` ` vi ` ) into a tuple
1868
+ of component-level values with types ` ts ` .
1869
1869
``` python
1870
- def lift_sync_values (cx , max_flat , vi , ts ):
1870
+ def lift_flat_values (cx , max_flat , vi , ts ):
1871
1871
flat_types = flatten_types(ts)
1872
1872
if len (flat_types) > max_flat:
1873
1873
return lift_heap_values(cx, vi, ts)
1874
1874
else :
1875
1875
return [ lift_flat(cx, vi, t) for t in ts ]
1876
1876
1877
- def lift_async_values (cx , vi , ts ):
1878
- if len (ts) == 0 :
1879
- _ = vi.next(' i32' )
1880
- return []
1881
- flat_types = flatten_types(ts)
1882
- if len (flat_types) == 1 and flat_types[0 ] == ' i32' :
1883
- assert (len (ts) == 1 )
1884
- return [ lift_flat(cx, vi, ts[0 ]) ]
1885
- else :
1886
- return lift_heap_values(cx, vi, ts)
1887
-
1888
1877
def lift_heap_values (cx , vi , ts ):
1889
1878
ptr = vi.next(' i32' )
1890
1879
tuple_type = Tuple(ts)
@@ -1893,36 +1882,26 @@ def lift_heap_values(cx, vi, ts):
1893
1882
return list (load(cx, ptr, tuple_type).values())
1894
1883
```
1895
1884
1896
- Symmetrically, the ` lower_(sync|async)_values ` functions define how to lower a
1897
- list of component-level values ` vs ` of types ` ts ` into a list of core values.
1898
- As already described for [ ` flatten ` ] ( #flattening ) above, lowering handles the
1899
- greater-than-` max_flat ` case by either allocating storage with ` realloc ` or
1900
- accepting a caller-allocated buffer as an out-param:
1885
+ Symmetrically, the ` lower_flat_values ` function defines how to lower a
1886
+ list of component-level values ` vs ` of types ` ts ` into a list of core
1887
+ values. As already described for [ ` flatten ` ] ( #flattening ) above,
1888
+ lowering handles the greater-than-` max_flat ` case by either allocating
1889
+ storage with ` realloc ` or accepting a caller-allocated buffer as an
1890
+ out-param:
1901
1891
``` python
1902
- def lower_sync_values (cx , max_flat , vs , ts , out_param = None ):
1903
- inst = cx.inst
1904
- assert (inst.may_leave)
1905
- inst.may_leave = False
1892
+ def lower_flat_values (cx , max_flat , vs , ts , out_param = None ):
1893
+ assert (cx.inst.may_leave)
1894
+ cx.inst.may_leave = False
1906
1895
flat_types = flatten_types(ts)
1907
1896
if len (flat_types) > max_flat:
1908
1897
flat_vals = lower_heap_values(cx, vs, ts, out_param)
1909
1898
else :
1910
1899
flat_vals = []
1911
1900
for i in range (len (vs)):
1912
1901
flat_vals += lower_flat(cx, vs[i], ts[i])
1913
- inst.may_leave = True
1902
+ cx. inst.may_leave = True
1914
1903
return flat_vals
1915
1904
1916
- def lower_async_values (cx , vs , ts , out_param ):
1917
- if len (ts) == 0 :
1918
- _ = out_param.next(' i32' )
1919
- return
1920
- inst = cx.inst
1921
- assert (inst.may_leave)
1922
- inst.may_leave = False
1923
- lower_heap_values(cx, vs, ts, out_param)
1924
- inst.may_leave = True
1925
-
1926
1905
def lower_heap_values (cx , vs , ts , out_param ):
1927
1906
tuple_type = Tuple(ts)
1928
1907
tuple_value = {str (i): v for i,v in enumerate (vs)}
@@ -1999,9 +1978,9 @@ async def canon_lift(opts, inst, callee, ft, caller, on_block, on_start, on_retu
1999
1978
task = SyncTask(opts, inst, caller, on_block)
2000
1979
await task.enter()
2001
1980
2002
- flat_args = lower_sync_values (task, MAX_FLAT_PARAMS , on_start(), ft.param_types())
1981
+ flat_args = lower_flat_values (task, MAX_FLAT_PARAMS , on_start(), ft.param_types())
2003
1982
flat_results = await call_and_trap_on_throw(callee, task, flat_args)
2004
- on_return(lift_sync_values (task, MAX_FLAT_RESULTS , CoreValueIter(flat_results), ft.result_types()))
1983
+ on_return(lift_flat_values (task, MAX_FLAT_RESULTS , CoreValueIter(flat_results), ft.result_types()))
2005
1984
2006
1985
if opts.post_return is not None :
2007
1986
[] = await call_and_trap_on_throw(opts.post_return, task, flat_results)
@@ -2095,10 +2074,10 @@ async def canon_lower(opts, callee, ft, task, flat_args):
2095
2074
task.on_block()
2096
2075
task.on_block = None
2097
2076
def on_start ():
2098
- return lift_sync_values (subtask, MAX_FLAT_PARAMS , flat_args, ft.param_types())
2077
+ return lift_flat_values (subtask, MAX_FLAT_PARAMS , flat_args, ft.param_types())
2099
2078
def on_return (results ):
2100
2079
nonlocal flat_results
2101
- flat_results = lower_sync_values (subtask, MAX_FLAT_RESULTS , results, ft.result_types(), flat_args)
2080
+ flat_results = lower_flat_values (subtask, MAX_FLAT_RESULTS , results, ft.result_types(), flat_args)
2102
2081
await callee(task, on_block, on_start, on_return)
2103
2082
task.inst.calling_sync_import = False
2104
2083
subtask.finish()
@@ -2110,10 +2089,10 @@ async def canon_lower(opts, callee, ft, task, flat_args):
2110
2089
eager_result.set_result(' block' )
2111
2090
def on_start ():
2112
2091
subtask.start()
2113
- return lift_async_values (subtask, flat_args, ft.param_types())
2092
+ return lift_flat_values (subtask, 1 , flat_args, ft.param_types())
2114
2093
def on_return (results ):
2115
2094
subtask.return_()
2116
- lower_async_values (subtask, results, ft.result_types(), flat_args)
2095
+ lower_flat_values (subtask, 0 , results, ft.result_types(), flat_args)
2117
2096
await callee(task, on_block, on_start, on_return)
2118
2097
subtask.finish()
2119
2098
if not eager_result.done():
@@ -2313,7 +2292,7 @@ async def canon_task_start(task, core_ft, flat_args):
2313
2292
trap_if(core_ft != flatten_functype(CanonicalOptions(), FuncType([], task.ft.params), ' lower' ))
2314
2293
task.start()
2315
2294
args = task.on_start()
2316
- flat_results = lower_sync_values (task, MAX_FLAT_RESULTS , args, task.ft.param_types(), CoreValueIter(flat_args))
2295
+ flat_results = lower_flat_values (task, MAX_FLAT_RESULTS , args, task.ft.param_types(), CoreValueIter(flat_args))
2317
2296
assert (len (core_ft.results) == len (flat_results))
2318
2297
return flat_results
2319
2298
```
@@ -2342,7 +2321,7 @@ async def canon_task_return(task, core_ft, flat_args):
2342
2321
trap_if(task.opts.sync)
2343
2322
trap_if(core_ft != flatten_functype(CanonicalOptions(), FuncType(task.ft.results, []), ' lower' ))
2344
2323
task.return_()
2345
- results = lift_sync_values (task, MAX_FLAT_PARAMS , CoreValueIter(flat_args), task.ft.result_types())
2324
+ results = lift_flat_values (task, MAX_FLAT_PARAMS , CoreValueIter(flat_args), task.ft.result_types())
2346
2325
task.on_return(results)
2347
2326
assert (len (core_ft.results) == 0 )
2348
2327
return []
0 commit comments