File Coverage

lib/Signature/Attribute/Alias.xs
Criterion Covered Total %
statement 23 23 100.0
branch 7 8 87.5
condition n/a
subroutine n/a
pod n/a
total 30 31 96.7


line stmt bran cond sub pod time code
1             /* You may distribute under the terms of either the GNU General Public License
2             * or the Artistic License (the same terms as Perl itself)
3             *
4             * (C) Paul Evans, 2023 -- leonerd@leonerd.org.uk
5             */
6             #define PERL_NO_GET_CONTEXT
7              
8             #include "EXTERN.h"
9             #include "perl.h"
10             #include "XSUB.h"
11              
12             #include "XSParseSublike.h"
13              
14             #define HAVE_PERL_VERSION(R, V, S) \
15             (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S))))))
16              
17             /* A horrible hack. We'll replace the op_ppaddr of the varop while leaving
18             * the rest of the op structure alone
19             */
20 2           static OP *pp_argelem_alias(pTHX)
21             {
22             /* Much copypaste from bleadperl's pp_argelem in pp.c */
23             SV ** padentry;
24 2           OP *o = PL_op;
25 2           AV *defav = GvAV(PL_defgv); /* @_ */
26 2           IV ix = PTR2IV(cUNOP_AUXo->op_aux);
27              
28 2           padentry = &(PAD_SVl(o->op_targ));
29 2           save_clearsv(padentry);
30              
31 2           SV **svp = av_fetch(defav, ix, FALSE);
32 2 50         *padentry = svp ? SvREFCNT_inc(*svp) : &PL_sv_undef;
33              
34 2           return o->op_next;
35             }
36              
37 5           static void apply_Alias(pTHX_ struct XPSSignatureParamContext *ctx, SV *attrvalue, void **attrdata_ptr, void *funcdata)
38             {
39 5           PADNAME *pn = PadnamelistARRAY(PL_comppad_name)[ctx->padix];
40 5 100         if(PadnamePV(pn)[0] != '$')
41 1           croak("Can only apply the :Alias attribute to scalar parameters");
42 4 100         if(ctx->is_named)
43 1           croak("Cannot apply the :Alias attribute to a named parameter");
44 3           }
45              
46 3           static void post_defop_Alias(pTHX_ struct XPSSignatureParamContext *ctx, void *attrdata, void *funcdata)
47             {
48 3 100         if(ctx->defop)
49 1           croak("Cannot apply the :Alias attribute to a parameter with a defaulting expression");
50              
51 2           OP *varop = ctx->varop;
52             assert(varop);
53             assert((varop->op_private & OPpARGELEM_MASK) == OPpARGELEM_SV);
54             assert(!(varop->op_flags & OPf_STACKED));
55              
56 2           varop->op_ppaddr = &pp_argelem_alias;
57 2           }
58              
59             static const struct XPSSignatureAttributeFuncs funcs_Alias = {
60             .ver = XSPARSESUBLIKE_ABI_VERSION,
61             .permit_hintkey = "Signature::Attribute::Alias/Alias",
62              
63             .apply = apply_Alias,
64             .post_defop = post_defop_Alias,
65             };
66              
67             MODULE = Signature::Attribute::Alias PACKAGE = Signature::Attribute::Alias
68              
69             BOOT:
70 3           boot_xs_parse_sublike(0.19);
71              
72             register_xps_signature_attribute("Alias", &funcs_Alias, NULL);