line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
#include "EXTERN.h" |
3
|
|
|
|
|
|
|
#include "perl.h" |
4
|
|
|
|
|
|
|
#include "XSUB.h" |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
MODULE = Sub::Inject PACKAGE = Sub::Inject |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
#ifndef intro_my /* perl 5.22+ */ |
11
|
|
|
|
|
|
|
# define intro_my() Perl_intro_my(aTHX) |
12
|
|
|
|
|
|
|
#endif |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#define is_code(sv) (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
void |
17
|
|
|
|
|
|
|
sub_inject(...) |
18
|
|
|
|
|
|
|
CODE: |
19
|
|
|
|
|
|
|
int argi; |
20
|
|
|
|
|
|
|
PADLIST *pl; |
21
|
|
|
|
|
|
|
PADOFFSET off; |
22
|
2
|
50
|
|
|
|
|
if (!PL_compcv) |
23
|
0
|
|
|
|
|
|
Perl_croak(aTHX_ |
24
|
|
|
|
|
|
|
"sub_inject can only be called at compile time"); |
25
|
2
|
50
|
|
|
|
|
if (items % 2) |
26
|
0
|
|
|
|
|
|
Perl_croak(aTHX_ |
27
|
|
|
|
|
|
|
"Odd number of elements in sub_inject"); |
28
|
|
|
|
|
|
|
|
29
|
2
|
|
|
|
|
|
pl = CvPADLIST(PL_compcv); |
30
|
2
|
|
|
|
|
|
ENTER; |
31
|
2
|
|
|
|
|
|
SAVESPTR(PL_comppad_name); PL_comppad_name = PadlistNAMES(pl); |
32
|
2
|
|
|
|
|
|
SAVESPTR(PL_comppad); PL_comppad = PadlistARRAY(pl)[1]; |
33
|
2
|
|
|
|
|
|
SAVESPTR(PL_curpad); PL_curpad = PadARRAY(PL_comppad); |
34
|
4
|
100
|
|
|
|
|
for (argi=0; argi < items; argi += 2) { |
35
|
2
|
50
|
|
|
|
|
if (!is_code(ST(argi+1))) |
|
|
50
|
|
|
|
|
|
36
|
0
|
|
|
|
|
|
Perl_croak(aTHX_ |
37
|
|
|
|
|
|
|
"Not a subroutine reference at sub_inject() argument %d", argi+1); |
38
|
2
|
|
|
|
|
|
SV *name = ST(argi); |
39
|
|
|
|
|
|
|
CV *cv = (CV *)SvRV(ST(argi+1)); |
40
|
2
|
|
|
|
|
|
off = pad_add_name_sv(sv_2mortal(newSVpvf("&%"SVf,name)), |
41
|
|
|
|
|
|
|
padadd_STATE, 0, 0); |
42
|
2
|
|
|
|
|
|
SvREFCNT_dec(PL_curpad[off]); |
43
|
4
|
|
|
|
|
|
PL_curpad[off] = SvREFCNT_inc(cv); |
44
|
|
|
|
|
|
|
} |
45
|
2
|
|
|
|
|
|
LEAVE; |
46
|
2
|
|
|
|
|
|
intro_my(); |