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
|
|
|
|
|
|