File: func.xs

package info (click to toggle)
libxs-parse-sublike-perl 0.37-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 516 kB
  • sloc: ansic: 944; perl: 930; sh: 6; makefile: 3
file content (108 lines) | stat: -rw-r--r-- 3,519 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*  You may distribute under the terms of either the GNU General Public License
 *  or the Artistic License (the same terms as Perl itself)
 *
 *  (C) Paul Evans, 2020-2023 -- leonerd@leonerd.org.uk
 */

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "XSParseSublike.h"

#if PERL_REVISION > 5 || (PERL_REVISION == 5 && PERL_VERSION >= 26)
#  define HAVE_SUB_PARAM_ATTRIBUTES
#endif

static const struct XSParseSublikeHooks parse_func_hooks = {
  .ver            = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/func",
  .flags          = XS_PARSE_SUBLIKE_FLAG_ALLOW_PKGNAME,
};

static const struct XSParseSublikeHooks parse_nfunc_hooks = {
  .ver            = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/nfunc",
  .flags = XS_PARSE_SUBLIKE_FLAG_SIGNATURE_NAMED_PARAMS,
};

static const struct XSParseSublikeHooks parse_afunc_hooks = {
  .ver            = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/afunc",
  .flags = XS_PARSE_SUBLIKE_FLAG_SIGNATURE_PARAM_ATTRIBUTES,
};

static const struct XSParseSublikeHooks parse_nafunc_hooks = {
  .ver            = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/nafunc",
  .flags = XS_PARSE_SUBLIKE_FLAG_SIGNATURE_NAMED_PARAMS|XS_PARSE_SUBLIKE_FLAG_SIGNATURE_PARAM_ATTRIBUTES,
};

static const struct XSParseSublikeHooks parse_nopkgfunc_hooks = {
  .ver            = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/func",
};

#ifdef HAVE_SUB_PARAM_ATTRIBUTES
static void apply_Attribute(pTHX_ struct XPSSignatureParamContext *ctx, SV *attrvalue, void **attrdata_ptr, void *funcdata)
{
  /* TODO: maybe the context should store a lexname string? */
  PADNAME *pn = PadnamelistARRAY(PL_comppad_name)[ctx->padix];

  AV *av = get_av("main::ATTRIBUTE_APPLIED", GV_ADD);

  av_push(av, newSVpvf("%s%" SVf,
    ctx->is_named ? ":" : "", PadnameSV(pn)));
  av_push(av, newSVsv(attrvalue));
}


static void post_defop_Attribute(pTHX_ struct XPSSignatureParamContext *ctx, void *attrdata, void *funcdata)
{
  /* OP* pointer values won't mean much to pureperl code, but we can at least
   * store UVs and assert them not zero
   */

  HV *n = newHV();
  hv_stores(n, "op",    newSVuv(PTR2UV(ctx->op)));
  hv_stores(n, "varop", newSVuv(PTR2UV(ctx->varop)));
  hv_stores(n, "defop", newSVuv(PTR2UV(ctx->defop)));

  AV *av = get_av("main::ATTRIBUTE_SAW_OPTREES", GV_ADD);

  av_push(av, newRV_noinc((SV *)n));

  /* Give the attribute a runtime side-effect so we can test that our returned
   * optree is invoked
   */
  GV *countergv = gv_fetchpvs("main::ATTRIBUTE_INVOKED", GV_ADD, SVt_IV);
  OP *incop = newUNOP(OP_PREINC, 0,
    newUNOP(OP_RV2SV, 0,
      newGVOP(OP_GV, 0, (GV *)SvREFCNT_inc(countergv))));

  ctx->op = op_append_elem(OP_LINESEQ, ctx->op, incop);
}

static const struct XPSSignatureAttributeFuncs attr_funcs = {
  .ver = XSPARSESUBLIKE_ABI_VERSION,
  .permit_hintkey = "t::func/Attribute",

  .apply      = apply_Attribute,
  .post_defop = post_defop_Attribute,
};
#endif

MODULE = t::func  PACKAGE = t::func

BOOT:
  boot_xs_parse_sublike(0);

  register_xs_parse_sublike("func",   &parse_func_hooks,   NULL);
  register_xs_parse_sublike("nfunc",  &parse_nfunc_hooks,  NULL);
  register_xs_parse_sublike("afunc",  &parse_afunc_hooks,  NULL);
  register_xs_parse_sublike("nafunc", &parse_nafunc_hooks, NULL);

  register_xs_parse_sublike("nopkgfunc",   &parse_nopkgfunc_hooks,   NULL);
#ifdef HAVE_SUB_PARAM_ATTRIBUTES
  register_xps_signature_attribute("Attribute", &attr_funcs, NULL);
#endif