File Coverage

src/xs/function.cc
Criterion Covered Total %
statement 37 37 100.0
branch 18 34 52.9
condition n/a
subroutine n/a
pod n/a
total 55 71 77.4


line stmt bran cond sub pod time code
1             #include "function.h"
2             #include "catch.h"
3              
4             namespace xs { namespace func {
5              
6             Sv::payload_marker_t marker;
7              
8 36           static bool init () {
9 142           marker.svt_free = [](pTHX_ SV*, MAGIC* mg) -> int {
10 35           auto fc = reinterpret_cast(mg->mg_ptr);
11 35 50         delete fc;
12 35           return 0;
13 71           };
14 36           return true;
15             }
16 36           static const bool _init = init();
17              
18 50           static void XS_function_call (pTHX_ CV* cv) { xs::throw_guard(cv, [=](){
19 25           dVAR; dXSARGS;
20 25           SP -= items;
21 50 50         Sub sub(cv);
22 25           auto fc = reinterpret_cast(sub.payload(&marker).ptr);
23 25 50         if (!fc) throw "invalid function->sub subroutine";
24 48 100         auto ret = fc->call(&ST(0), items);
25 23 100         if (!ret) XSRETURN_EMPTY;
26 9 50         mXPUSHs(ret.detach());
    0          
    50          
27 9           XSRETURN(1);
28 25 50         }); }
29              
30 35           static Sub clone_anon_xsub (CV* proto) {
31             dTHX;
32 35 50         CV* cv = MUTABLE_CV(newSV_type(SvTYPE(proto)));
33 35           CvFLAGS(cv) = CvFLAGS(proto) & ~(CVf_CLONE|CVf_WEAKOUTSIDE|CVf_CVGV_RC);
34 35           CvCLONED_on(cv);
35 35           CvFILE(cv) = CvFILE(proto);
36 35 50         CvGV_set(cv,CvGV(proto));
    50          
37 35 50         CvSTASH_set(cv, CvSTASH(proto));
38 35           CvISXSUB_on(cv);
39 35           CvXSUB(cv) = CvXSUB(proto);
40             #if PERL_VERSION >= 22
41             #ifndef PERL_IMPLICIT_CONTEXT
42 35           CvHSCXT(cv) = &PL_stack_sp;
43             #else
44             PoisonPADLIST(cv);
45             #endif
46             #endif
47 35           CvANON_on(cv);
48 35 50         return Sub::noinc(cv);
49             }
50              
51 36           static PERL_THREAD_LOCAL CV* proto = newXS(nullptr, &XS_function_call, "");
52              
53 35           Sub create_sub (IFunctionCaller* fc) {
54 35           auto ret = clone_anon_xsub(proto);
55 35 50         ret.payload_attach(fc, &marker);
56 35           return ret;
57             }
58              
59 144 50         }}
    50