Skip to content

Commit 649f7fd

Browse files
committed
Limit number of flags to 32
Resolves #370
1 parent affacdc commit 649f7fd

File tree

4 files changed

+24
-47
lines changed

4 files changed

+24
-47
lines changed

design/mvp/Binary.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ defvaltype ::= pvt:<primvaltype> => pvt
186186
| 0x71 case*:vec(<case>) => (variant case+) (if |case*| > 0)
187187
| 0x70 t:<valtype> => (list t)
188188
| 0x6f t*:vec(<valtype>) => (tuple t+) (if |t*| > 0)
189-
| 0x6e l*:vec(<label'>) => (flags l+) (if |l*| > 0)
189+
| 0x6e l*:vec(<label'>) => (flags l+) (if 0 < |l*| <= 32)
190190
| 0x6d l*:vec(<label'>) => (enum l+) (if |l*| > 0)
191191
| 0x6b t:<valtype> => (option t)
192192
| 0x6a t?:<valtype>? u?:<valtype>? => (result t? (error u)?)

design/mvp/CanonicalABI.md

+11-22
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ back to sequences of `i32`s when there are more than 32 flags.
158158
```python
159159
def alignment_flags(labels):
160160
n = len(labels)
161+
assert(0 < n <= 32)
161162
if n <= 8: return 1
162163
if n <= 16: return 2
163164
return 4
@@ -216,13 +217,10 @@ def elem_size_variant(cases):
216217

217218
def elem_size_flags(labels):
218219
n = len(labels)
219-
assert(n > 0)
220+
assert(0 < n <= 32)
220221
if n <= 8: return 1
221222
if n <= 16: return 2
222-
return 4 * num_i32_flags(labels)
223-
224-
def num_i32_flags(labels):
225-
return math.ceil(len(labels) / 32)
223+
return 4
226224
```
227225

228226
### Call Context
@@ -1584,7 +1582,7 @@ def flatten_type(t):
15841582
case String() | List(_) : return ['i32', 'i32']
15851583
case Record(fields) : return flatten_record(fields)
15861584
case Variant(cases) : return flatten_variant(cases)
1587-
case Flags(labels) : return ['i32'] * num_i32_flags(labels)
1585+
case Flags(labels) : return ['i32']
15881586
case Own(_) | Borrow(_) : return ['i32']
15891587
```
15901588

@@ -1755,16 +1753,12 @@ def wrap_i64_to_i32(i):
17551753
return i % (1 << 32)
17561754
```
17571755

1758-
Finally, flags are lifted by OR-ing together all the flattened `i32` values
1759-
and then lifting to a record the same way as when loading flags from linear
1760-
memory.
1756+
Finally, flags are lifted by lifting to a record the same way as when loading
1757+
flags from linear memory.
17611758
```python
17621759
def lift_flat_flags(vi, labels):
1763-
i = 0
1764-
shift = 0
1765-
for _ in range(num_i32_flags(labels)):
1766-
i |= (vi.next('i32') << shift)
1767-
shift += 32
1760+
assert(0 < len(labels) <= 32)
1761+
i = vi.next('i32')
17681762
return unpack_flags_from_int(i, labels)
17691763
```
17701764

@@ -1857,16 +1851,11 @@ def lower_flat_variant(cx, v, cases):
18571851
return [case_index] + payload
18581852
```
18591853

1860-
Finally, flags are lowered by slicing the bit vector into `i32` chunks:
1854+
Finally, flags are lowered by packing the flags into on `i32` bitvector.
18611855
```python
18621856
def lower_flat_flags(v, labels):
1863-
i = pack_flags_into_int(v, labels)
1864-
flat = []
1865-
for _ in range(num_i32_flags(labels)):
1866-
flat.append(i & 0xffffffff)
1867-
i >>= 32
1868-
assert(i == 0)
1869-
return flat
1857+
assert(0 < len(labels) <= 32)
1858+
return [pack_flags_into_int(v, labels)]
18701859
```
18711860

18721861
### Lifting and Lowering Values

design/mvp/canonical-abi/definitions.py

+8-18
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ def max_case_alignment(cases):
221221

222222
def alignment_flags(labels):
223223
n = len(labels)
224+
assert(0 < n <= 32)
224225
if n <= 8: return 1
225226
if n <= 16: return 2
226227
return 4
@@ -266,13 +267,10 @@ def elem_size_variant(cases):
266267

267268
def elem_size_flags(labels):
268269
n = len(labels)
269-
assert(n > 0)
270+
assert(0 < n <= 32)
270271
if n <= 8: return 1
271272
if n <= 16: return 2
272-
return 4 * num_i32_flags(labels)
273-
274-
def num_i32_flags(labels):
275-
return math.ceil(len(labels) / 32)
273+
return 4
276274

277275
### Call Context
278276

@@ -1100,7 +1098,7 @@ def flatten_type(t):
11001098
case String() | List(_) : return ['i32', 'i32']
11011099
case Record(fields) : return flatten_record(fields)
11021100
case Variant(cases) : return flatten_variant(cases)
1103-
case Flags(labels) : return ['i32'] * num_i32_flags(labels)
1101+
case Flags(labels) : return ['i32']
11041102
case Own(_) | Borrow(_) : return ['i32']
11051103

11061104
def flatten_record(fields):
@@ -1222,11 +1220,8 @@ def wrap_i64_to_i32(i):
12221220
return i % (1 << 32)
12231221

12241222
def lift_flat_flags(vi, labels):
1225-
i = 0
1226-
shift = 0
1227-
for _ in range(num_i32_flags(labels)):
1228-
i |= (vi.next('i32') << shift)
1229-
shift += 32
1223+
assert(0 < len(labels) <= 32)
1224+
i = vi.next('i32')
12301225
return unpack_flags_from_int(i, labels)
12311226

12321227
### Flat Lowering
@@ -1294,13 +1289,8 @@ def lower_flat_variant(cx, v, cases):
12941289
return [case_index] + payload
12951290

12961291
def lower_flat_flags(v, labels):
1297-
i = pack_flags_into_int(v, labels)
1298-
flat = []
1299-
for _ in range(num_i32_flags(labels)):
1300-
flat.append(i & 0xffffffff)
1301-
i >>= 32
1302-
assert(i == 0)
1303-
return flat
1292+
assert(0 < len(labels) <= 32)
1293+
return [pack_flags_into_int(v, labels)]
13041294

13051295
### Lifting and Lowering Values
13061296

design/mvp/canonical-abi/run_tests.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def test_name():
114114
test(t, [2], {'a':False,'b':True})
115115
test(t, [3], {'a':True,'b':True})
116116
test(t, [4], {'a':False,'b':False})
117-
test(Flags([str(i) for i in range(33)]), [0xffffffff,0x1], { str(i):True for i in range(33) })
117+
test(Flags([str(i) for i in range(32)]), [0xffffffff], { str(i):True for i in range(32) })
118118
t = Variant([Case('x',U8()),Case('y',F32()),Case('z',None)])
119119
test(t, [0,42], {'x': 42})
120120
test(t, [0,256], {'x': 0})
@@ -304,12 +304,10 @@ def test_heap(t, expect, args, byte_array):
304304
[0xff,0xff,0x1,0, 0,0,0,0])
305305
test_heap(t, v, [0,2],
306306
[0xff,0xff,0x3,0, 0,0,0,0])
307-
t = List(Flags([str(i) for i in range(33)]))
308-
v = [{ str(i):b for i in range(33) } for b in [True,False]]
307+
t = List(Flags([str(i) for i in range(32)]))
308+
v = [{ str(i):b for i in range(32) } for b in [True,False]]
309309
test_heap(t, v, [0,2],
310-
[0xff,0xff,0xff,0xff,0x1,0,0,0, 0,0,0,0,0,0,0,0])
311-
test_heap(t, v, [0,2],
312-
[0xff,0xff,0xff,0xff,0x3,0,0,0, 0,0,0,0,0,0,0,0])
310+
[0xff,0xff,0xff,0xff, 0,0,0,0])
313311

314312
def test_flatten(t, params, results):
315313
expect = CoreFuncType(params, results)

0 commit comments

Comments
 (0)