if (SvTYPE(gv) == SVt_PVGV)
return cv_const_sv(GvCVu(gv));
- return SvROK(gv) ? SvRV(gv) : NULL;
+ return SvROK(gv) && SvTYPE(SvRV(gv)) != SVt_PVAV ? SvRV(gv) : NULL;
}
GP *
if (has_constant) {
/* The constant has to be a simple scalar type. */
switch (SvTYPE(has_constant)) {
- case SVt_PVAV:
case SVt_PVHV:
case SVt_PVCV:
case SVt_PVFM:
}
static void const_sv_xsub(pTHX_ CV* cv);
+static void const_av_xsub(pTHX_ CV* cv);
/*
SV *
Perl_cv_const_sv(pTHX_ const CV *const cv)
{
+ SV *sv;
PERL_UNUSED_CONTEXT;
if (!cv)
return NULL;
if (!(SvTYPE(cv) == SVt_PVCV || SvTYPE(cv) == SVt_PVFM))
return NULL;
- return CvCONST(cv) ? MUTABLE_SV(CvXSUBANY(cv).any_ptr) : NULL;
+ sv = CvCONST(cv) ? MUTABLE_SV(CvXSUBANY(cv).any_ptr) : NULL;
+ if (sv && SvTYPE(sv) == SVt_PVAV) return NULL;
+ return sv;
}
/* op_const_sv: examine an optree to determine whether it's in-lineable.
and so doesn't get free()d. (It's expected to be from the C pre-
processor __FILE__ directive). But we need a dynamically allocated one,
and we need it to get freed. */
- cv = newXS_len_flags(name, len, const_sv_xsub, file ? file : "", "",
+ cv = newXS_len_flags(name, len,
+ sv && SvTYPE(sv) == SVt_PVAV
+ ? const_av_xsub
+ : const_sv_xsub,
+ file ? file : "", "",
&sv, XS_DYNAMIC_FILENAME | flags);
CvXSUBANY(cv).any_ptr = SvREFCNT_inc_simple(sv);
CvCONST_on(cv);
XSRETURN(1);
}
+static void
+const_av_xsub(pTHX_ CV* cv)
+{
+ dVAR;
+ dXSARGS;
+ AV * const av = MUTABLE_AV(XSANY.any_ptr);
+ SP -= items;
+ assert(av);
+#ifndef DEBUGGING
+ if (!av) {
+ XSRETURN(0);
+ }
+#endif
+ if (SvRMAGICAL(av))
+ Perl_croak(aTHX_ "Magical list constants are not supported");
+ if (GIMME_V != G_ARRAY) {
+ EXTEND(SP, 1);
+ ST(0) = newSViv((IV)AvFILLp(av)+1);
+ XSRETURN(1);
+ }
+ EXTEND(SP, AvFILLp(av)+1);
+ Copy(AvARRAY(av), &ST(0), AvFILLp(av)+1, SV *);
+ XSRETURN(AvFILLp(av)+1);
+}
+
/*
* Local variables:
* c-indentation-style: bsd
See also L<attributes.pm|attributes>.
+=item Magical list constants are not supported
+
+(F) You assigned a magical array to a stash element, and then tried
+to use the subroutine from the same slot. You are asking Perl to do
+something it cannot do, details subject to change between Perl versions.
+
=item Malformed integer in [] in pack
(F) Between the brackets enclosing a numeric repeat count only digits
use warnings;
-plan( tests => 245 );
+plan( tests => 250 );
# type coercion on assignment
$foo = 'foo';
is (eval 'biff', "Value", "Constant has correct value");
is (ref \$::{biff}, 'GLOB', "Symbol table has full typeglob");
+$::{yarrow} = [4,5,6];
+is join("-", eval "yarrow()"), '4-5-6', 'array ref as stash elem';
+is ref $::{yarrow}, "ARRAY", 'stash elem is still array ref after use';
+is join("-", eval "&yarrow"), '4-5-6', 'calling const list with &';
+is join("-", eval "&yarrow(1..10)"), '4-5-6', 'const list ignores & args';
+is prototype "yarrow", "", 'const list has "" prototype';
+is eval "yarrow", 3, 'const list in scalar cx returns length';
+
{
use vars qw($glook $smek $foof);
# Check reference assignment isn't affected by the SV type (bug #38439)
format =
.
-foreach my $value ([1,2,3], {1=>2}, *STDOUT{IO}, \&ok, *STDOUT{FORMAT}) {
+foreach my $value ({1=>2}, *STDOUT{IO}, \&ok, *STDOUT{FORMAT}) {
# *STDOUT{IO} returns a reference to a PVIO. As it's blessed, ref returns
# IO::Handle, which isn't what we want.
my $type = $value;
use open qw( :utf8 :std );
use warnings;
-plan( tests => 212 );
+plan( tests => 211 );
# type coersion on assignment
$ᕘ = 'ᕘ';
format =
.
- foreach my $value ([1,2,3], {1=>2}, *STDOUT{IO}, \&ok, *STDOUT{FORMAT}) {
+ foreach my $value ({1=>2}, *STDOUT{IO}, \&ok, *STDOUT{FORMAT}) {
# *STDOUT{IO} returns a reference to a PVIO. As it's blessed, ref returns
# IO::Handle, which isn't what we want.
my $type = $value;