Define bounded lists#640
Conversation
lukewagner
left a comment
There was a problem hiding this comment.
Thanks! This is looking generally good, a few comments:
| `none` case of an optional immediate.) | ||
| * 🔧 for fixed-sized lists the length of the list must be larger than 0 to pass | ||
| validation. | ||
| * 🔧 for fixed-sized lists (`0x67`) the length of the list must be larger than |
There was a problem hiding this comment.
Pre-existing, but it looks like the grammar already covers this twice: once by using <u32> (unsigned) and once with the (if maxlen > 0). We could also remove the (if maxlen > 0). But should we specify a maximum for maxlen?
There was a problem hiding this comment.
For u32, zero is valid and the maxlen > 0 checks forbids zero. What would be a legitimate upper bound... i32::MAX?
There was a problem hiding this comment.
There's already (just recently added) a MAX_LIST_BYTE_LENGTH = 228-1. That's just bytes, but even still, it seems like a reasonable upper bound.
There was a problem hiding this comment.
Ok, defined that bound in BINARY.md but where would we check this in definitions.py ?
|
Associated with Implement WIT Fixed-Length-Lists |
Cherry-picked the essence of cpetig's commit d2874eb from https://github.com/cpetig/component-model/tree/bounded-lists, adapted to the current codebase (ptr_type/opts threading, updated class names). Bounded strings are intentionally excluded. Co-authored-by: Christof Petig <christof.petig@arcor.de>
- Add trap_if(actual_len > maybe_length) to lift_flat_list, mirroring the existing trap in load_list's heap path - Add over-length trap tests for both flat and heap lifting - Add alignment test for bounded list of U32 (verifies 3-byte padding after U8 length prefix)
- fix memory bounds checking - improve integration with existing list load/store code - fix indentation - avoid default argument - more readable load/store recipe
Replace the expanded-element flat representation with a pointer-based one for direct fixed and bounded length lists. Add contains_direct_list and type_has_direct_list_result helpers to detect when result types contain such lists, forcing memory-based returns. Update test expectations and add new roundtrip tests for the pointer-based flat ABI.
|
Here is another shot at an ABI tweak for efficient passing of fixed/bounded lists. It is already implemented in the commit I just pushed. @cpetig 's ideas with refinement by discussion, my write-up; more versatile / less invasive compared to my previous proposal. Flat ABI for Fixed and Bounded Length ListsMotivationThe current flat ABI for fixed length lists expands all N element slots If the current approach was naively adopted for bounded length lists A second, independent motivation is that fixed and bounded length lists This proposal replaces the expanded-element flat representation with a Flat representation
Memory representation
bounded actual len: smallest integer type that can represent values up to (including) N Lowering and LiftingParametersBelow explanation is for bounded length lists which carry a runtime length. If all core params fit within
ResultsMemory-passing is enforced when even a single direct fixed/bounded length list is in the result type -
Fused allocationWhen multiple direct lists exist among parameters and passing flat, the host might service |
|
Thanks for the clear write-up (and sorry for the delay replying)! That all sounds pretty good; just one suggestion: if a component exports a function with type |
I addressed that in the trailing "fused allocation" section - yes it should be done but we need not guarantee that by design. In practice, the host can alloc one big chunk for everything and hand out pointers to subobjects (list1, list2, list3, etc. correctly aligned and sized of course). The allocation will continue to be owned by the host.
Passing all params in a param-area, even if callee side only, feels a bit inefficient. We should try to utilize registers for non-list value passing. But that's just my 2 cents... PS: |
I think the host can do that when given a list, b/c the host can do whatever, but if we're talking about lowering a list into the guest, the
I suppose, but I would expect this to be amortized by the cost of at least 1 |
Sorry if I'm repeating myself. I might be missing some crucial C-M insight...
What obligation would make fusion impossible? |
Add bounded lists (
list<T, ..N>)Closes #385.