@@ -1538,10 +1538,7 @@ guaranteed to be a no-op on the first iteration because the record as
15381538a whole starts out aligned (as asserted at the top of ` load ` ).
15391539
15401540Variants 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.
15451542While the code below appears to perform case-label lookup at runtime, a normal
15461543implementation can build the appropriate index tables at compile-time so that
15471544variant-passing is always O(1) and not involving string operations.
@@ -1553,24 +1550,9 @@ def load_variant(cx, ptr, cases):
15531550 trap_if(case_index >= len (cases))
15541551 c = cases[case_index]
15551552 ptr = align_to(ptr, max_case_alignment(cases))
1556- case_label = case_label_with_refinements(c, cases)
15571553 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) }
15741556```
15751557
15761558Flags are converted from a bit-vector to a dictionary whose keys are
@@ -2023,12 +2005,13 @@ def store_record(cx, v, ptr, fields):
20232005 ptr += elem_size(f.t)
20242006```
20252007
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.
20322015``` python
20332016def store_variant (cx , v , ptr , cases ):
20342017 case_index, case_value = match_case(v, cases)
@@ -2041,13 +2024,10 @@ def store_variant(cx, v, ptr, cases):
20412024 store(cx, case_value, c.t, ptr)
20422025
20432026def 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)
20512031```
20522032
20532033Flags are converted from a dictionary to a bit-vector by iterating
@@ -2414,7 +2394,7 @@ def lift_flat_variant(cx, vi, cases):
24142394 v = lift_flat(cx, CoerceValueIter(), c.t)
24152395 for have in flat_types:
24162396 _ = vi.next(have)
2417- return { case_label_with_refinements(c, cases) : v }
2397+ return { c.label : v }
24182398
24192399def wrap_i64_to_i32 (i ):
24202400 assert (0 <= i < (1 << 64 ))
0 commit comments