Re: [PATCH] Optimize split //
[p5sagit/p5-mst-13.2.git] / ext / Devel / PPPort / parts / inc / call
CommitLineData
adfe19db 1################################################################################
2##
a89b7ab8 3## $Revision: 12 $
adfe19db 4## $Author: mhx $
a89b7ab8 5## $Date: 2007/03/23 17:57:58 +0100 $
adfe19db 6##
7################################################################################
8##
d2dacc4f 9## Version 3.x, Copyright (C) 2004-2007, Marcus Holland-Moritz.
adfe19db 10## Version 2.x, Copyright (C) 2001, Paul Marquess.
11## Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
12##
13## This program is free software; you can redistribute it and/or
14## modify it under the same terms as Perl itself.
15##
16################################################################################
17
18=provides
19
20eval_pv
21eval_sv
22call_sv
23call_pv
24call_argv
25call_method
a89b7ab8 26load_module
27vload_module
adfe19db 28
29=implementation
30
31/* Replace: 1 */
32__UNDEFINED__ call_sv perl_call_sv
33__UNDEFINED__ call_pv perl_call_pv
34__UNDEFINED__ call_argv perl_call_argv
35__UNDEFINED__ call_method perl_call_method
36
37__UNDEFINED__ eval_sv perl_eval_sv
a89b7ab8 38
39__UNDEFINED__ PERL_LOADMOD_DENY 0x1
40__UNDEFINED__ PERL_LOADMOD_NOIMPORT 0x2
41__UNDEFINED__ PERL_LOADMOD_IMPORT_OPS 0x4
42
adfe19db 43/* Replace: 0 */
44
45/* Replace perl_eval_pv with eval_pv */
46/* eval_pv depends on eval_sv */
47
48#ifndef eval_pv
49#if { NEED eval_pv }
50
51SV*
52eval_pv(char *p, I32 croak_on_error)
53{
54 dSP;
55 SV* sv = newSVpv(p, 0);
56
57 PUSHMARK(sp);
58 eval_sv(sv, G_SCALAR);
59 SvREFCNT_dec(sv);
60
61 SPAGAIN;
62 sv = POPs;
63 PUTBACK;
64
65 if (croak_on_error && SvTRUE(GvSV(errgv)))
66 croak(SvPVx(GvSV(errgv), na));
67
68 return sv;
69}
70
71#endif
72#endif
73
a89b7ab8 74#ifndef vload_module
75#if { NEED vload_module }
76
77void
78vload_module(U32 flags, SV *name, SV *ver, va_list *args)
79{
80 dTHR;
81 dVAR;
82 OP *veop, *imop;
83
84 OP * const modname = newSVOP(OP_CONST, 0, name);
85 /* 5.005 has a somewhat hacky force_normal that doesn't croak on
86 SvREADONLY() if PL_compling is true. Current perls take care in
87 ck_require() to correctly turn off SvREADONLY before calling
88 force_normal_flags(). This seems a better fix than fudging PL_compling
89 */
90 SvREADONLY_off(((SVOP*)modname)->op_sv);
91 modname->op_private |= OPpCONST_BARE;
92 if (ver) {
93 veop = newSVOP(OP_CONST, 0, ver);
94 }
95 else
96 veop = NULL;
97 if (flags & PERL_LOADMOD_NOIMPORT) {
98 imop = sawparens(newNULLLIST());
99 }
100 else if (flags & PERL_LOADMOD_IMPORT_OPS) {
101 imop = va_arg(*args, OP*);
102 }
103 else {
104 SV *sv;
105 imop = NULL;
106 sv = va_arg(*args, SV*);
107 while (sv) {
108 imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv));
109 sv = va_arg(*args, SV*);
110 }
111 }
112 {
113 const line_t ocopline = PL_copline;
114 COP * const ocurcop = PL_curcop;
115 const int oexpect = PL_expect;
116
117#if { VERSION >= 5.004 }
118 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
119 veop, modname, imop);
120#else
121 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(),
122 modname, imop);
123#endif
124 PL_expect = oexpect;
125 PL_copline = ocopline;
126 PL_curcop = ocurcop;
127 }
128}
129
130#endif
131#endif
132
133/* load_module depends on vload_module */
134
135#ifndef load_module
136#if { NEED load_module }
137
138void
139load_module(U32 flags, SV *name, SV *ver, ...)
140{
141 va_list args;
142 va_start(args, ver);
143 vload_module(flags, name, ver, &args);
144 va_end(args);
145}
146
147#endif
148#endif
149
adfe19db 150=xsinit
151
152#define NEED_eval_pv
a89b7ab8 153#define NEED_load_module
154#define NEED_vload_module
adfe19db 155
156=xsubs
157
158I32
159G_SCALAR()
160 CODE:
161 RETVAL = G_SCALAR;
162 OUTPUT:
163 RETVAL
164
165I32
166G_ARRAY()
167 CODE:
168 RETVAL = G_ARRAY;
169 OUTPUT:
170 RETVAL
171
172I32
173G_DISCARD()
174 CODE:
175 RETVAL = G_DISCARD;
176 OUTPUT:
177 RETVAL
178
179void
180eval_sv(sv, flags)
181 SV* sv
182 I32 flags
183 PREINIT:
184 I32 i;
185 PPCODE:
186 PUTBACK;
187 i = eval_sv(sv, flags);
188 SPAGAIN;
189 EXTEND(SP, 1);
190 PUSHs(sv_2mortal(newSViv(i)));
191
192void
193eval_pv(p, croak_on_error)
194 char* p
195 I32 croak_on_error
196 PPCODE:
197 PUTBACK;
198 EXTEND(SP, 1);
199 PUSHs(eval_pv(p, croak_on_error));
200
201void
202call_sv(sv, flags, ...)
203 SV* sv
204 I32 flags
205 PREINIT:
206 I32 i;
207 PPCODE:
208 for (i=0; i<items-2; i++)
209 ST(i) = ST(i+2); /* pop first two args */
210 PUSHMARK(SP);
211 SP += items - 2;
212 PUTBACK;
213 i = call_sv(sv, flags);
214 SPAGAIN;
215 EXTEND(SP, 1);
216 PUSHs(sv_2mortal(newSViv(i)));
217
218void
219call_pv(subname, flags, ...)
220 char* subname
221 I32 flags
222 PREINIT:
223 I32 i;
224 PPCODE:
225 for (i=0; i<items-2; i++)
226 ST(i) = ST(i+2); /* pop first two args */
227 PUSHMARK(SP);
228 SP += items - 2;
229 PUTBACK;
230 i = call_pv(subname, flags);
231 SPAGAIN;
232 EXTEND(SP, 1);
233 PUSHs(sv_2mortal(newSViv(i)));
234
235void
236call_argv(subname, flags, ...)
237 char* subname
238 I32 flags
239 PREINIT:
240 I32 i;
241 char *args[8];
242 PPCODE:
243 if (items > 8) /* play safe */
244 XSRETURN_UNDEF;
245 for (i=2; i<items; i++)
246 args[i-2] = SvPV_nolen(ST(i));
247 args[items-2] = NULL;
248 PUTBACK;
249 i = call_argv(subname, flags, args);
250 SPAGAIN;
251 EXTEND(SP, 1);
252 PUSHs(sv_2mortal(newSViv(i)));
253
254void
255call_method(methname, flags, ...)
256 char* methname
257 I32 flags
258 PREINIT:
259 I32 i;
260 PPCODE:
261 for (i=0; i<items-2; i++)
262 ST(i) = ST(i+2); /* pop first two args */
263 PUSHMARK(SP);
264 SP += items - 2;
265 PUTBACK;
266 i = call_method(methname, flags);
267 SPAGAIN;
268 EXTEND(SP, 1);
269 PUSHs(sv_2mortal(newSViv(i)));
270
a89b7ab8 271void
272load_module(flags, name, version, ...)
273 U32 flags
274 SV *name
275 SV *version
276 CODE:
277 /* Both SV parameters are donated to the ops built inside
278 load_module, so we need to bump the refcounts. */
279 SvREFCNT_inc(name);
280 SvREFCNT_inc(version);
281 Perl_load_module(aTHX_ flags, name, version, NULL);
282
283=tests plan => 46
adfe19db 284
285sub eq_array
286{
287 my($a, $b) = @_;
288 join(':', @$a) eq join(':', @$b);
289}
290
291sub f
292{
293 shift;
294 unshift @_, 'b';
295 pop @_;
296 @_, defined wantarray ? wantarray ? 'x' : 'y' : 'z';
297}
298
299my $obj = bless [], 'Foo';
300
301sub Foo::meth
302{
303 return 'bad_self' unless @_ && ref $_[0] && ref($_[0]) eq 'Foo';
304 shift;
305 shift;
306 unshift @_, 'b';
307 pop @_;
308 @_, defined wantarray ? wantarray ? 'x' : 'y' : 'z';
309}
310
311my $test;
312
313for $test (
314 # flags args expected description
315 [ &Devel::PPPort::G_SCALAR, [ ], [ qw(y 1) ], '0 args, G_SCALAR' ],
316 [ &Devel::PPPort::G_SCALAR, [ qw(a p q) ], [ qw(y 1) ], '3 args, G_SCALAR' ],
317 [ &Devel::PPPort::G_ARRAY, [ ], [ qw(x 1) ], '0 args, G_ARRAY' ],
318 [ &Devel::PPPort::G_ARRAY, [ qw(a p q) ], [ qw(b p x 3) ], '3 args, G_ARRAY' ],
319 [ &Devel::PPPort::G_DISCARD, [ ], [ qw(0) ], '0 args, G_DISCARD' ],
320 [ &Devel::PPPort::G_DISCARD, [ qw(a p q) ], [ qw(0) ], '3 args, G_DISCARD' ],
321)
322{
323 my ($flags, $args, $expected, $description) = @$test;
324 print "# --- $description ---\n";
325 ok(eq_array( [ &Devel::PPPort::call_sv(\&f, $flags, @$args) ], $expected));
326 ok(eq_array( [ &Devel::PPPort::call_sv(*f, $flags, @$args) ], $expected));
327 ok(eq_array( [ &Devel::PPPort::call_sv('f', $flags, @$args) ], $expected));
328 ok(eq_array( [ &Devel::PPPort::call_pv('f', $flags, @$args) ], $expected));
329 ok(eq_array( [ &Devel::PPPort::call_argv('f', $flags, @$args) ], $expected));
330 ok(eq_array( [ &Devel::PPPort::eval_sv("f(qw(@$args))", $flags) ], $expected));
331 ok(eq_array( [ &Devel::PPPort::call_method('meth', $flags, $obj, @$args) ], $expected));
332};
333
334ok(&Devel::PPPort::eval_pv('f()', 0), 'y');
335ok(&Devel::PPPort::eval_pv('f(qw(a b c))', 0), 'y');
336
a89b7ab8 337ok(!defined $::{'less::'}, 1, "Hadn't loaded less yet");
338Devel::PPPort::load_module(0, "less", undef);
339ok(defined $::{'less::'}, 1, "Have now loaded less");