Some functions take arguments that point to the terminating NUL
character of a string. This commit adds a way to declare in embed.fnc
that a given argument is of that kind.
Some header files in the Perl core have guards to keep a
recursive #include from compiling them again. This is standard practice
in C coding, and I was surprised at how many headers don't have
it. These seem to rely on only being included from perl.h, which does
have its own guard.
Most of the guards use a common naming convention. If the file is named
foo.h, the guard is named 'PERL_FOO_H'. Often, though, a trailing
underscore is added, 'PERL_FOO_H_', making the convention slightly
fuzzy. The 'PERL_' is not added if the file 'foo' already includes
'perl' in its name,
Those rules are enough to describe all the guards in the core, except
for the outliers in this commit, plus perl.h.
There are occasions in various Perl scripts that examine our source that
we want to create a pattern that matches the header guard name for a
particular file. In spite of the slight fuzziness, that's easy using
the above rules, except for the ones in this commit, and perl.h.
It would be better for that code to not have to worry about the
outliers, and since these are arbitrary names, we can just change them
to follow the rules that already apply to most.
This commit changes the names of the outliers so that the only file the
rules don't apply to is perl.h. Its guard is named H_PERL. That
spelling is used in Encode, so it's not so easy to change it seamlessly.
I'm willing to live with it continuing to be an outlier for the code I
write.
This commit adds an entry in embed.fnc for S_is_dup_mode, removing the
assert and __attribute lines in op.c.
The proximal cause for this commit is that I tried compiling with
Perl_assert() enabled, which resulted in a lot of compiler warnings
because of the __attribute__non_null__ line
But I also think it is better to not hand-roll things unless absolutely
necessary. Changes someone makes to the general scheme are not likely
to be propagated to the hand-rolled items.
This is checking that the argument is an ASCII \w that isn't an
underscore. But in this range, that is identical to an alphanumeric,
which there is already a macro for, so use that single macro instead of
the two.
Discovered while working on another module, in many amagic_call() will
use the current context when calling the overload sub, but these APIs
might be called in XS code that simply needs a comparison, regardless
of the current OP context.
do_ncmp() expects simple SVs and for overloaded SVs will just compare
the SvNV() of each SV, mishandling the case where the 0+ overload
returns a large UV or IV that isn't exactly representable as an NV.
# Conflicts:
# ext/XS-APItest/t/sv_numeq.t
# ext/XS-APItest/t/sv_numne.t
# sv.c
some refactoring next, since sv_numeq_flags and sv_numne_flags are
similar.
Used a separate test file since putting every sv_num*() variant in the
one file would be ugly
Addresses GH #23918 but isn't a direct fix
As noted by https://github.com/Perl/perl5/issues/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.
* 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
https://github.com/Perl/perl5/issues/24027
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.
Rather than copy-pasted code in two places, define a helper function to
call from both. This also accounts for minor (but currently
inconsequential) differences in behaviour between the two copy-pasted
locations, that seem to have drifted apart over time.
Adds consistency and avoids a weird cornercase in which due to
non-standard circumstances these SVs are already magical.
These only happen at compile-time so performance hit of performing an
extra SvTYPE() check is not critical.
`for ( X .. Y ) {}` ranges take values in IV range for X & Y.
(If X & Y are NVs or "look like numbers", the IV values are derived.)
The in-range check is performed on every call to `pp_enteriter` using
`S_outside_integer`, which derives the NV value for X & Y (calling
`sv_upgrade` if X & Y are not SVt_NV or SVt_PVNV+), and performs multiple
checks on the NV values to see if they fit within IV range.
However, if X & Y are `SvIOK_notUV` then the values fit within IV range
by definition and the whole `S_outside_integer` work is unnecessary.
This commit adds a hot branch that checks for `SvIOK_notUV` X & Y with
values `> -1` and skips `S_outside_integer` if the checks are successful.
The `> -1` checks seem like they shouldn't be necessary (again, if it's
an SvIOK_notUV, by definition the value fits in an IV), but are there
to workaround introducing test failures in t/op/range.t. (This attempts
to confirm that test values just below IV_MIN are not accepted in
parsing, but because of NV imprecision, seems to expect some wrong
results. `> -1` is an arbitrary chosen constraint that fits the bill.)
_Gcov_ of a perl build and test_harness run shows this hot branch
predominating:
```
6056933: 2682: if (SvIOK_notUV(sv) && SvIVX(sv) > -1 &&
6048750: 2683: SvIOK_notUV(right) && SvIVX(right) > -1) {
6044776: 2684: cx->cx_type |= CXt_LOOP_LAZYIV;
6044776: 2685: cx->blk_loop.state_u.lazyiv.cur = SvIVX(sv);
6044776: 2686: cx->blk_loop.state_u.lazyiv.end = SvIVX(right);
6044776: 2687: rpp_popfree_2_NN();
-: 2688: }
12157: 2689: else if (RANGE_IS_NUMERIC(sv,right)) {
12097: 2690: cx->cx_type |= CXt_LOOP_LAZYIV;
24183: 2691: if (S_outside_integer(aTHX_ sv) ||
12086: 2692: S_outside_integer(aTHX_ right))
22: 2693: DIE(aTHX_ "Range iterator outside integer range");
12075: 2694: cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
12075: 2695: cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
12075: 2696: rpp_popfree_2_NN();
-: 2697: }
```
perf confirms:
* eliminated calls to `S_outside_integer`, Perl_sv_2nv_flags, `Perl_isinfnan`
* Perl_pp_enteriter also runs slightly faster.
This makes a difference of 7 minutes per `make test`, so the default
should be to run the tests in parallel. There is one instance of
`make test ; make install` that still exercises the `make test` code
path, for completeness.
Otherwise, it's possible that later steps add new macros that `embed.pl`
would have wanted to add to its list of things to `#undef`, requiring a
second run of `make regen`.
By running embed.pl last, we ensure this happens in the right order the
first time.
Fixes#24083. Fixes#24084.
In d957e95daa0143d60933d96d6cbfb69eee6d6269 I changed the definitions of
IV_DIG and UV_DIG to depend on IV_BITS and UV_BITS respectively,
creating the latter in perl.h. These had only visibility to the perl
core. But I forgot that the _DIG forms were visible everywhere, so the
_BITS forms needed to be as well.
This commit merely documents all of them as public API (which should
have been the case all along anyway), which automatically causes their
visibility to be made everywhere.