forked from rgs/Sub-Identify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Identify.xs
75 lines (66 loc) · 1.87 KB
/
Identify.xs
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
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#ifndef CvISXSUB
# define CvISXSUB(cv) CvXSUB(cv)
#endif
/*
get_code_info:
Pass in a coderef, returns:
[ $pkg_name, $coderef_name ] ie:
[ 'Foo::Bar', 'new' ]
*/
MODULE = Sub::Identify PACKAGE = Sub::Identify
PROTOTYPES: ENABLE
void
get_code_info(coderef)
SV* coderef
PREINIT:
char* name;
char* pkg;
PPCODE:
if (SvOK(coderef) && SvROK(coderef) && SvTYPE(SvRV(coderef)) == SVt_PVCV) {
coderef = SvRV(coderef);
if (CvGV(coderef)) {
name = GvNAME( CvGV(coderef) );
pkg = HvNAME( GvSTASH(CvGV(coderef)) );
EXTEND(SP, 2);
PUSHs(sv_2mortal(newSVpvn(pkg, strlen(pkg))));
PUSHs(sv_2mortal(newSVpvn(name, strlen(name))));
}
else {
/* sub is being compiled: bail out and return nothing. */
}
}
void
get_code_location(coderef)
SV* coderef
PREINIT:
char* file;
line_t line;
PPCODE:
if (SvOK(coderef) && SvROK(coderef) && SvTYPE(SvRV(coderef)) == SVt_PVCV) {
coderef = SvRV(coderef);
if (CvSTART(coderef) && !CvISXSUB(coderef)) {
file = CvFILE(coderef);
line = CopLINE((const COP*)CvSTART(coderef));
EXTEND(SP, 2);
PUSHs(sv_2mortal(newSVpvn(file, strlen(file))));
PUSHs(sv_2mortal(newSViv(line)));
}
}
#if PERL_VERSION >= 16
bool
is_sub_constant(coderef)
SV* coderef
CODE:
if (SvOK(coderef) && SvROK(coderef) && SvTYPE(SvRV(coderef)) == SVt_PVCV) {
coderef = SvRV(coderef);
RETVAL = CvPROTO(coderef) && CvPROTOLEN(coderef) == 0 && CvCONST(coderef);
}
else
RETVAL = 0;
OUTPUT:
RETVAL
#endif