@@ -1538,10 +1538,7 @@ guaranteed to be a no-op on the first iteration because the record as
1538
1538
a whole starts out aligned (as asserted at the top of ` load ` ).
1539
1539
1540
1540
Variants are loaded using the order of the cases in the type to determine the
1541
- case index, assigning ` 0 ` to the first case, ` 1 ` to the next case, etc. To
1542
- support the subtyping allowed by ` refines ` , a lifted variant value semantically
1543
- includes a full ordered list of its ` refines ` case labels so that the lowering
1544
- code (defined below) can search this list to find a case label it knows about.
1541
+ case index, assigning ` 0 ` to the first case, ` 1 ` to the next case, etc.
1545
1542
While the code below appears to perform case-label lookup at runtime, a normal
1546
1543
implementation can build the appropriate index tables at compile-time so that
1547
1544
variant-passing is always O(1) and not involving string operations.
@@ -1553,24 +1550,9 @@ def load_variant(cx, ptr, cases):
1553
1550
trap_if(case_index >= len (cases))
1554
1551
c = cases[case_index]
1555
1552
ptr = align_to(ptr, max_case_alignment(cases))
1556
- case_label = case_label_with_refinements(c, cases)
1557
1553
if c.t is None :
1558
- return { case_label: None }
1559
- return { case_label: load(cx, ptr, c.t) }
1560
-
1561
- def case_label_with_refinements (c , cases ):
1562
- label = c.label
1563
- while c.refines is not None :
1564
- c = cases[find_case(c.refines, cases)]
1565
- label += ' |' + c.label
1566
- return label
1567
-
1568
- def find_case (label , cases ):
1569
- matches = [i for i,c in enumerate (cases) if c.label == label]
1570
- assert (len (matches) <= 1 )
1571
- if len (matches) == 1 :
1572
- return matches[0 ]
1573
- return - 1
1554
+ return { c.label: None }
1555
+ return { c.label: load(cx, ptr, c.t) }
1574
1556
```
1575
1557
1576
1558
Flags are converted from a bit-vector to a dictionary whose keys are
@@ -2023,12 +2005,13 @@ def store_record(cx, v, ptr, fields):
2023
2005
ptr += elem_size(f.t)
2024
2006
```
2025
2007
2026
- Variants are stored using the ` | ` -separated list of ` refines ` cases built
2027
- by ` case_label_with_refinements ` (above) to iteratively find a matching case (which
2028
- validation guarantees will succeed). While this code appears to do O(n) string
2029
- matching, a normal implementation can statically fuse ` store_variant ` with its
2030
- matching ` load_variant ` to ultimately build a dense array that maps producer's
2031
- case indices to the consumer's case indices.
2008
+ Variant values are represented as Python dictionaries containing exactly one
2009
+ entry whose key is the label of the lifted case and whose value is the
2010
+ (optional) case payload. While this code appears to do an O(n) search of the
2011
+ ` variant ` type for a matching case label, a normal implementation can
2012
+ statically fuse ` store_variant ` with its matching ` load_variant ` to ultimately
2013
+ build a dense array that maps producer's case indices to the consumer's case
2014
+ indices.
2032
2015
``` python
2033
2016
def store_variant (cx , v , ptr , cases ):
2034
2017
case_index, case_value = match_case(v, cases)
@@ -2041,13 +2024,10 @@ def store_variant(cx, v, ptr, cases):
2041
2024
store(cx, case_value, c.t, ptr)
2042
2025
2043
2026
def match_case (v , cases ):
2044
- assert (len (v.keys()) == 1 )
2045
- key = list (v.keys())[0 ]
2046
- value = list (v.values())[0 ]
2047
- for label in key.split(' |' ):
2048
- case_index = find_case(label, cases)
2049
- if case_index != - 1 :
2050
- return (case_index, value)
2027
+ [label] = v.keys()
2028
+ [index] = [i for i,c in enumerate (cases) if c.label == label]
2029
+ [value] = v.values()
2030
+ return (index, value)
2051
2031
```
2052
2032
2053
2033
Flags are converted from a dictionary to a bit-vector by iterating
@@ -2414,7 +2394,7 @@ def lift_flat_variant(cx, vi, cases):
2414
2394
v = lift_flat(cx, CoerceValueIter(), c.t)
2415
2395
for have in flat_types:
2416
2396
_ = vi.next(have)
2417
- return { case_label_with_refinements(c, cases) : v }
2397
+ return { c.label : v }
2418
2398
2419
2399
def wrap_i64_to_i32 (i ):
2420
2400
assert (0 <= i < (1 << 64 ))
0 commit comments