Allow multivariable foreach to use refaliases#24094
Merged
leonerd merged 5 commits intoPerl:bleadfrom Jan 22, 2026
Merged
Conversation
New helper functions to avoid some copy-paste. Also because I'm otherwise about to add a third copy.
Currently these are all scalar variables, but soon I will add the ability for iteration variables to be refaliases, so they won't necessarily all be scalars any more.
* Define a new private op constant OPpITER_REFALIAS * Presence of this flag on OP_ITER means the iteration var is a refalias * Throw away the LVREF/REFGEN part of the optree in favour of just setting this flag This change is useful on its own, and also a good stepping-stone towards being able to implement multiple refalias variables in foreach; as per Perl#24027
70dacfa to
59b135e
Compare
As noted by Perl#24027, while multivar foreach and refalias foreach have each been available separately for some time now, it wasn't possible to combine the two until now. This current implementation does have limits on the number of variables in total are allowed in a multivariable foreach loop if any are refaliases (no more than 256), and which ones can be refaliases (none past the 24th) that are all to do with the way I am abusing the U32 `op_targ` field to store the variable count in the lower 8 bits, and a bitmask of which vars are refaliases in the upper 24 bits. I decided to do that as it means I don't have to make the `OP_ITER` op any larger - such as by expanding it to an UNOP_AUX to give it that extra storage space. In practice I don't imagine those limits will be a problem for any practical use-case. If in a future version we did want to expand on those limits, I think it would be possible by moving the `refalias_mask` storage to a PV stored in the UNOP_AUX vector, or somesuch.
59b135e to
0824dfe
Compare
tonycoz
approved these changes
Jan 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #24027
As noted by #24027, while multivar foreach and refalias foreach have each been available separately for some time now, it wasn't possible to combine the two until now.
This current implementation does have limits on the number of variables in total are allowed in a multivariable foreach loop if any are refaliases (no more than 256), and which ones can be refaliases (none past the 24th) that are all to do with the way I am abusing the U32
op_targfield to store the variable count in the lower 8 bits, and a bitmask of which vars are refaliases in the upper 24 bits. I decided to do that as it means I don't have to make theOP_ITERop any larger - such as by expanding it to an UNOP_AUX to give it that extra storage space. In practice I don't imagine those limits will be a problem for any practical use-case.If in a future version we did want to expand on those limits, I think it would be possible by moving the
refalias_maskstorage to a PV stored in the UNOP_AUX vector, or somesuch.