| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package xsub; |
|
2
|
|
|
|
|
|
|
$VERSION = 1.0; |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
my %XSUB; |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
sub import { |
|
7
|
1
|
|
|
1
|
|
3
|
my $p = shift; |
|
8
|
|
|
|
|
|
|
|
|
9
|
1
|
|
|
|
|
3
|
my ($package, $file, $line) = caller; |
|
10
|
|
|
|
|
|
|
|
|
11
|
1
|
|
|
|
|
2
|
my $source = pop; |
|
12
|
1
|
|
|
|
|
2
|
my $name = shift; |
|
13
|
1
|
50
|
33
|
|
|
13
|
my $prototype = @_ && $_[0] !~ /^:/ ? shift : undef; |
|
14
|
1
|
|
|
|
|
2
|
my $attributes = [@_]; |
|
15
|
1
|
|
|
|
|
3
|
s/^:// for @$attributes; |
|
16
|
|
|
|
|
|
|
|
|
17
|
1
|
|
|
|
|
8
|
my $xs = bless { |
|
18
|
|
|
|
|
|
|
name => $name, |
|
19
|
|
|
|
|
|
|
source => $source, |
|
20
|
|
|
|
|
|
|
package => $package, |
|
21
|
|
|
|
|
|
|
file => $file, |
|
22
|
|
|
|
|
|
|
line => $line, |
|
23
|
|
|
|
|
|
|
prototype => $prototype, |
|
24
|
|
|
|
|
|
|
attributes => $attributes, |
|
25
|
|
|
|
|
|
|
}, $p; |
|
26
|
|
|
|
|
|
|
|
|
27
|
1
|
50
|
|
|
|
4
|
if ($name) { |
|
28
|
1
|
50
|
|
|
|
4
|
my $pr = defined($prototype) ? "($prototype)" : ""; |
|
29
|
1
|
|
|
|
|
40
|
eval "package $package; sub $name $pr"; |
|
30
|
1
|
50
|
|
|
|
5
|
$@ and die $@; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
1
|
|
|
|
|
2
|
local *XSUB = \@{$XSUB{$file}}; |
|
|
1
|
|
|
|
|
4
|
|
|
34
|
1
|
|
|
|
|
326
|
push @XSUB, $xs; |
|
35
|
|
|
|
|
|
|
} |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub _reindent($$) { |
|
38
|
3
|
|
|
3
|
|
7
|
my $v = ' ' x shift; |
|
39
|
3
|
|
|
|
|
47
|
my @l = split /\n/, $_[0]; |
|
40
|
|
|
|
|
|
|
|
|
41
|
3
|
|
|
|
|
6
|
my $i = 0; |
|
42
|
3
|
|
66
|
|
|
27
|
$i++ while $i < @l && $l[$i] eq ''; |
|
43
|
3
|
50
|
33
|
|
|
19
|
$i < @l && $l[$i] =~ m/^(\s+)/ or return $_[0]; |
|
44
|
3
|
|
|
|
|
6
|
my $k = $1; |
|
45
|
|
|
|
|
|
|
|
|
46
|
3
|
|
|
|
|
161
|
s/^$k/$v/ for @l; |
|
47
|
3
|
|
|
|
|
48
|
join "\n", @l, ''; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub _unindent($) { |
|
51
|
2
|
|
|
2
|
|
5
|
_reindent(0, $_[0]) |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _compile { |
|
55
|
1
|
|
|
1
|
|
2
|
my ($c, $so) = @_; |
|
56
|
1
|
|
|
|
|
885
|
my $cmd = |
|
57
|
|
|
|
|
|
|
"$C{cc} $C{ccflags} -O3 $C{cccdlflags} " . |
|
58
|
|
|
|
|
|
|
"-I$C{archlib}/CORE $C{lddlflags} -o $so $c"; |
|
59
|
1
|
|
|
|
|
391713
|
my $x = system $cmd; |
|
60
|
1
|
50
|
|
|
|
2064
|
$x and die; |
|
61
|
0
|
0
|
|
|
|
0
|
-e $so or die; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub bootstrap { |
|
65
|
1
|
|
|
1
|
|
1
|
my $p = shift; |
|
66
|
1
|
|
|
|
|
4
|
my ($q, $qpm) = (caller)[0, 1]; |
|
67
|
1
|
|
|
|
|
1
|
my ($qc, $qso); |
|
68
|
|
|
|
|
|
|
|
|
69
|
1
|
|
|
|
|
2
|
local *XSUB = \@{$XSUB{$qpm}}; |
|
|
1
|
|
|
|
|
3
|
|
|
70
|
1
|
50
|
|
|
|
5
|
defined @XSUB or return; |
|
71
|
|
|
|
|
|
|
|
|
72
|
1
|
50
|
|
|
|
30
|
-e $qpm or die; |
|
73
|
1
|
50
|
|
|
|
7
|
$qpm =~ m/\.pm$/ or die; |
|
74
|
1
|
50
|
|
|
|
7
|
($qc = $qpm) =~ s/\.pm$/\.c/ or die; |
|
75
|
1
|
50
|
|
|
|
6
|
($qso = $qpm) =~ s/\.pm$/\.so/ or die; |
|
76
|
|
|
|
|
|
|
|
|
77
|
1
|
0
|
33
|
|
|
23
|
if (!-e $qso || (-M $qpm < -M $qso) || (-M __FILE__ < -M $qso)) { |
|
|
|
|
33
|
|
|
|
|
|
78
|
1
|
|
|
|
|
3
|
local *XS; |
|
79
|
1
|
50
|
|
|
|
284
|
open XS, '>', $qc or die; |
|
80
|
1
|
|
|
|
|
11
|
my $pre = select(XS); |
|
81
|
|
|
|
|
|
|
|
|
82
|
1
|
|
|
|
|
6
|
print _unindent qq{ |
|
83
|
|
|
|
|
|
|
#include "EXTERN.h" |
|
84
|
|
|
|
|
|
|
#include "perl.h" |
|
85
|
|
|
|
|
|
|
#include "XSUB.h" |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
#define __PACKAGE__ "$q" |
|
88
|
|
|
|
|
|
|
#define undef (&PL_sv_undef) |
|
89
|
|
|
|
|
|
|
#define true (&PL_sv_yes) |
|
90
|
|
|
|
|
|
|
#define yes true |
|
91
|
|
|
|
|
|
|
#define false (&PL_sv_no) |
|
92
|
|
|
|
|
|
|
#define no false |
|
93
|
|
|
|
|
|
|
#define unless(x) if (!(x)) |
|
94
|
|
|
|
|
|
|
#define wantarray (GIMME == G_ARRAY) |
|
95
|
|
|
|
|
|
|
#define wantvoid (GIMME == G_VOID) |
|
96
|
|
|
|
|
|
|
#define wantscalar (GIMME == G_SCALAR) |
|
97
|
|
|
|
|
|
|
}; |
|
98
|
|
|
|
|
|
|
|
|
99
|
1
|
|
|
|
|
3
|
print _unindent q{ |
|
100
|
|
|
|
|
|
|
#define _C_RETURN_AV(sv) { \ |
|
101
|
|
|
|
|
|
|
AV *av = (AV *)(sv); I32 n = 1 + AvFILL(av); \ |
|
102
|
|
|
|
|
|
|
EXTEND(SP, n); Copy(AvARRAY(av), SP + 1, n, SV *); SP += n; \ |
|
103
|
|
|
|
|
|
|
av_undef(av); \ |
|
104
|
|
|
|
|
|
|
PUTBACK; return; \ |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
#define _C_RETURN_SV(sv) { \ |
|
108
|
|
|
|
|
|
|
PUSHs(sv_2mortal(sv)); \ |
|
109
|
|
|
|
|
|
|
PUTBACK; return; \ |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
#define _C_DECLARE(name) XS(name) { \ |
|
113
|
|
|
|
|
|
|
dXSARGS; SP -= items; { \ |
|
114
|
|
|
|
|
|
|
SV *(_C_ ## name)(U32, SV **); \ |
|
115
|
|
|
|
|
|
|
SV *sv = (_C_ ## name)(items, &ST(0)); \ |
|
116
|
|
|
|
|
|
|
if (!sv) { PUTBACK; return; } \ |
|
117
|
|
|
|
|
|
|
if (SvTYPE(sv) == SVt_PVAV) \ |
|
118
|
|
|
|
|
|
|
_C_RETURN_AV(sv) \ |
|
119
|
|
|
|
|
|
|
else \ |
|
120
|
|
|
|
|
|
|
_C_RETURN_SV(sv) \ |
|
121
|
|
|
|
|
|
|
} \ |
|
122
|
|
|
|
|
|
|
} SV *_C_ ## name (UV argc, SV **argv) |
|
123
|
|
|
|
|
|
|
}; |
|
124
|
|
|
|
|
|
|
|
|
125
|
1
|
|
|
|
|
2
|
for (@XSUB) { |
|
126
|
1
|
50
|
|
|
|
12
|
unless ($$_{name}) { |
|
127
|
0
|
|
|
|
|
0
|
print "#line $$_{line} \"$$_{file}\"\n"; |
|
128
|
0
|
|
|
|
|
0
|
print _unindent($$_{source}), "\n"; |
|
129
|
0
|
|
|
|
|
0
|
next; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
|
|
132
|
1
|
|
|
|
|
4
|
(my $name = "XS_$$_{package}_$$_{name}") =~ s/::/__/g; |
|
133
|
|
|
|
|
|
|
|
|
134
|
1
|
|
|
|
|
2
|
print "\n"; |
|
135
|
1
|
|
|
|
|
3
|
print "_C_DECLARE($name) {\n"; |
|
136
|
1
|
|
|
|
|
4
|
print "#line $$_{line} \"$$_{file}\"\n"; |
|
137
|
1
|
|
|
|
|
2
|
print _reindent(2, $$_{source}); |
|
138
|
1
|
|
|
|
|
3
|
print "}\n"; |
|
139
|
|
|
|
|
|
|
# print "#define $$_{name} _C_$name\n"; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
|
|
142
|
1
|
|
|
|
|
3
|
(my $boot_q = "boot_$q") =~ s/::/__/g; |
|
143
|
1
|
|
|
|
|
2
|
print "\nXS($boot_q) {\n"; |
|
144
|
1
|
|
|
|
|
3
|
for (@XSUB) { |
|
145
|
1
|
50
|
|
|
|
3
|
$$_{name} or next; |
|
146
|
1
|
|
|
|
|
3
|
my $realname = "$$_{package}::$$_{name}"; |
|
147
|
1
|
|
|
|
|
3
|
(my $name = "XS_$$_{package}_$$_{name}") =~ s/::/__/g; |
|
148
|
|
|
|
|
|
|
|
|
149
|
1
|
|
|
|
|
1
|
my $pr = $$_{prototype}; |
|
150
|
1
|
50
|
|
|
|
3
|
defined $pr and $pr =~ s/\\/\\\\/g; |
|
151
|
|
|
|
|
|
|
|
|
152
|
1
|
|
|
|
|
2
|
print " newXS"; |
|
153
|
1
|
50
|
|
|
|
4
|
print "proto" if defined $pr; |
|
154
|
1
|
|
|
|
|
3
|
print "(\"$realname\", $name, __FILE__"; |
|
155
|
1
|
50
|
|
|
|
4
|
print ", \"$pr\"" if defined $pr; |
|
156
|
1
|
|
|
|
|
8
|
print ");\n"; |
|
157
|
|
|
|
|
|
|
} |
|
158
|
1
|
|
|
|
|
2
|
print "}\n"; |
|
159
|
|
|
|
|
|
|
|
|
160
|
1
|
|
|
|
|
3
|
select($pre); |
|
161
|
1
|
|
|
|
|
51
|
close XS; |
|
162
|
|
|
|
|
|
|
|
|
163
|
1
|
|
|
|
|
6
|
require Config; |
|
164
|
1
|
|
|
|
|
4
|
local *C = \%Config::Config; |
|
165
|
|
|
|
|
|
|
|
|
166
|
1
|
|
|
|
|
24
|
unlink($qso); |
|
167
|
1
|
|
|
|
|
3
|
_compile($qc, $qso); |
|
168
|
0
|
|
|
|
|
|
unlink($qc); |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
|
|
171
|
0
|
|
|
|
|
|
require DynaLoader; |
|
172
|
0
|
0
|
|
|
|
|
$qso =~ m<^/> or $qso = "./$qso"; |
|
173
|
0
|
0
|
|
|
|
|
my $libref = DynaLoader::dl_load_file($qso, 0) or die; |
|
174
|
0
|
|
|
|
|
|
(my $boot_q = "boot_$q") =~ s/::/__/g; |
|
175
|
0
|
0
|
|
|
|
|
my $symref = DynaLoader::dl_find_symbol($libref, $boot_q) or die; |
|
176
|
0
|
0
|
|
|
|
|
DynaLoader::dl_install_xsub($boot_q, $symref, $qso) or die; |
|
177
|
|
|
|
|
|
|
|
|
178
|
0
|
|
|
|
|
|
&{$boot_q}; |
|
|
0
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
|
180
|
0
|
|
|
|
|
|
require attributes; |
|
181
|
0
|
|
|
|
|
|
for (@XSUB) { |
|
182
|
0
|
0
|
0
|
|
|
|
$$_{name} && @{$$_{attributes}} or next; |
|
|
0
|
|
|
|
|
|
|
|
183
|
0
|
|
|
|
|
|
for my $a (@{$$_{attributes}}) { |
|
|
0
|
|
|
|
|
|
|
|
184
|
0
|
|
|
|
|
|
import attributes $$_{package}, \&{"$$_{package}::$$_{name}"}, $a; |
|
|
0
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
} |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
1 |