You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
flags: support flags that are just combinations of other flags, not taking a new bit. #660
flags gpu-color-write {
red,
green,
blue,
alpha,
all,
}
which is incorrect in that all shouldn't be a new flag, just a shorthand for a combination of all the other flags.
I think WIT should be changed to allow expressing named flag values that are just combinations of zero or more existing flags by allowing assigning flag values to either 0 or the bitwise or of one or more other named flags:
flags colors {
black = 0,
red,
green,
yellow = red | green,
blue,
magenta = red | blue,
purple = magenta,
cyan = green | blue,
white = red | green | blue,
}
note: I'm not planning on implementing this myself, so whoever's interested feel free to implement it whenever ready.
Thanks for filing; this seems like an interesting addition worth exploring!
So currently, flags is defined as a specialization of records (as a record-of-bool-valued fields). If we added just the | extension (the ability to define a flag as the combination of other preceding flags), I think that framing still makes sense. If we also add the ability to define flag values as integer constants, then we probably need to switch to thinking of flags more like integers. That's not necessarily a problem, and is quite natural for C and other low-level languages, but probably requires some extra discussion since it might change whether the bindings generators for non-low-level-languages spit out a number vs. a record with boolean fields. Actually, I don't know what, e.g., componentize-{js,py} already do for flags; maybe they already use numbers? Anyone know?
If we allow integer constants, there's also some questions of what the rules are for constants. E.g., can I have:
flags f {
a = 0x1,
b = 0x2,
c = 0x3
}
since c = a | b (and then would this be invalid if b was removed so that c was no longer the conjunction of multiple fields?) or do we only allow integer constants that are powers of 2 and non-powers-of-2 have to be expressed as conjunctions? I expect there are good answers, but it'll require some discussion of how much we want to lean into "they're just integers".
To wit, looking at the current lifting rules (in lift_flat_flags in CanonicalABI.md), there is not a trap on stray bits (i.e., invalid flags values), but stray bits also don't propagate across component boundaries (so on the receiving end, you can assume a valid flags value) which implies a masking operation. Masking would continue to work with only-powers-of-2-integer-constants, but wouldn't in the general case for arbitrary constants, so that's another consideration.
That's just some initial thoughts; happy to discuss more.
ah, i was proposing that only literally 0 would be accepted, not arbitrary integer constants. so in terms of a record of bools, it would just be the record value where all fields are false.
that said, I'm not against supporting integer constants if it makes sense.
So if we added |, I guess there's still a question of what JS bindings would do for combo values. Since there's also plenty of cases of Web APIs using JS numbers as bitfields (NodeFilter, compareDocumentPosition and, in WebGPU, GPUBufferUsage, GPUTextureUsage, etc), I wonder if the JS bindings should do that, and then each flags value can just be a Number-valued property. Probably also good for bindings performance. (cc @vados-cosmonic)
Activity
lukewagner commentedon Jun 15, 2026
Thanks for filing; this seems like an interesting addition worth exploring!
So currently,
flagsis defined as a specialization of records (as a record-of-bool-valued fields). If we added just the|extension (the ability to define a flag as the combination of other preceding flags), I think that framing still makes sense. If we also add the ability to define flag values as integer constants, then we probably need to switch to thinking offlagsmore like integers. That's not necessarily a problem, and is quite natural for C and other low-level languages, but probably requires some extra discussion since it might change whether the bindings generators for non-low-level-languages spit out a number vs. a record with boolean fields. Actually, I don't know what, e.g.,componentize-{js,py}already do forflags; maybe they already use numbers? Anyone know?If we allow integer constants, there's also some questions of what the rules are for constants. E.g., can I have:
flags f { a = 0x1, b = 0x2, c = 0x3 }since
c = a | b(and then would this be invalid ifbwas removed so thatcwas no longer the conjunction of multiple fields?) or do we only allow integer constants that are powers of 2 and non-powers-of-2 have to be expressed as conjunctions? I expect there are good answers, but it'll require some discussion of how much we want to lean into "they're just integers".To wit, looking at the current lifting rules (in
lift_flat_flagsin CanonicalABI.md), there is not a trap on stray bits (i.e., invalidflagsvalues), but stray bits also don't propagate across component boundaries (so on the receiving end, you can assume a validflagsvalue) which implies a masking operation. Masking would continue to work with only-powers-of-2-integer-constants, but wouldn't in the general case for arbitrary constants, so that's another consideration.That's just some initial thoughts; happy to discuss more.
programmerjake commentedon Jun 15, 2026
ah, i was proposing that only literally
0would be accepted, not arbitrary integer constants. so in terms of a record of bools, it would just be the record value where all fields are false.that said, I'm not against supporting integer constants if it makes sense.
dicej commentedon Jun 15, 2026
For reference,
componentize-pyusesenum.Flagwhen generating code for WIT flags, which appears to be compatible with integer constants.ComponentizeJSgenerates an object with a bunch of boolean fields: https://github.com/bytecodealliance/jco/blob/2fd05be4b34137e720fe91043d2ce1232f66ac4d/crates/js-component-bindgen/src/ts_bindgen.rs#L1222-L1234lukewagner commentedon Jun 15, 2026
@programmerjake Ahh, I see; just to indicate "no flags set". That nicely avoids a number of the trickier questions I listed.
@dicej Thanks!
So if we added
|, I guess there's still a question of what JS bindings would do for combo values. Since there's also plenty of cases of Web APIs using JS numbers as bitfields (NodeFilter,compareDocumentPositionand, in WebGPU,GPUBufferUsage,GPUTextureUsage, etc), I wonder if the JS bindings should do that, and then eachflagsvalue can just be aNumber-valued property. Probably also good for bindings performance. (cc @vados-cosmonic)lukewagner commentedon Jun 15, 2026
Oh, hah, I just got to #662 in my inbox queue, which does seem to want integer constants other than
0.programmerjake commentedon Jun 15, 2026
for integer values, we could continue to do masking and the mask would just be the bitwise or of all possible flags, so:
would mask by
0b1101.