Skip to content

Commit

Permalink
[perl #87064] eval no longer shares filters
Browse files Browse the repository at this point in the history
Before this commit:

commit f07ec6d
Author: Zefram <zefram@fysh.org>
Date:   Wed Oct 13 19:05:19 2010 +0100

    remove filter inheritance option from lex_start

    The only uses of lex_start that had the new_filter parameter false,
    to make the new lexer context share source filters with the previous
    lexer context, were uses with rsfp null, which therefore never invoked
    source filters.  Inheriting source filters from a logically unrelated
    file seems like a silly idea anyway.

string evals could inherit the same source filter space as the cur-
rently compiling code. Despite what the quoted commit message says,
sharing source filters allows filters to be inherited in both direc-
tions: A source filter created when the eval is being compiled also
applies to the file with which it is sharing its space.

There are at least 20 CPAN distributions relying on this behaviour
(or, rather, what could be considered a Test::More bug). So this com-
mit restores the source-filter-sharing capability. It does not change
the current API or make public the API for sharing source filters, as
this is supposed to be a temporary stop-gap measure for 5.14.
  • Loading branch information
Father Chrysostomos committed Apr 3, 2011
1 parent c2c97af commit 27fcb6e
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 7 deletions.
1 change: 1 addition & 0 deletions MANIFEST
Expand Up @@ -3633,6 +3633,7 @@ ext/XS-APItest/t/cleanup.t test stack behaviour on unwinding
ext/XS-APItest/t/cophh.t test COPHH API ext/XS-APItest/t/cophh.t test COPHH API
ext/XS-APItest/t/copyhints.t test hv_copy_hints_hv() API ext/XS-APItest/t/copyhints.t test hv_copy_hints_hv() API
ext/XS-APItest/t/customop.t XS::APItest: tests for custom ops ext/XS-APItest/t/customop.t XS::APItest: tests for custom ops
ext/XS-APItest/t/eval-filter.t Simple source filter/eval test
ext/XS-APItest/t/exception.t XS::APItest extension ext/XS-APItest/t/exception.t XS::APItest extension
ext/XS-APItest/t/grok.t XS::APItest: tests for grok* functions ext/XS-APItest/t/grok.t XS::APItest: tests for grok* functions
ext/XS-APItest/t/hash.t XS::APItest: tests for hash related APIs ext/XS-APItest/t/hash.t XS::APItest: tests for hash related APIs
Expand Down
7 changes: 6 additions & 1 deletion ext/XS-APItest/APItest.pm
Expand Up @@ -50,7 +50,7 @@ sub import {
} }
} }


our $VERSION = '0.27'; our $VERSION = '0.28';


use vars '$WARNINGS_ON_BOOTSTRAP'; use vars '$WARNINGS_ON_BOOTSTRAP';
use vars map "\$${_}_called_PP", qw(BEGIN UNITCHECK CHECK INIT END); use vars map "\$${_}_called_PP", qw(BEGIN UNITCHECK CHECK INIT END);
Expand Down Expand Up @@ -209,6 +209,11 @@ correctly by C<printf>.
Output is sent to STDOUT. Output is sent to STDOUT.
=item B<filter>
Installs a source filter that substitutes "e" for "o" (witheut regard fer
what it might be medifying).
=item B<call_sv>, B<call_pv>, B<call_method> =item B<call_sv>, B<call_pv>, B<call_method>
These exercise the C calls of the same names. Everything after the flags These exercise the C calls of the same names. Everything after the flags
Expand Down
25 changes: 25 additions & 0 deletions ext/XS-APItest/APItest.xs
Expand Up @@ -996,6 +996,26 @@ peep_xop(pTHX_ OP *o, OP *oldop)
av_push(MY_CXT.xop_record, newSVpvf("oldop:%"UVxf, PTR2UV(oldop))); av_push(MY_CXT.xop_record, newSVpvf("oldop:%"UVxf, PTR2UV(oldop)));
} }


static I32
filter_call(pTHX_ int idx, SV *buf_sv, int maxlen)
{
SV *my_sv = FILTER_DATA(idx);
char *p;
char *end;
int n = FILTER_READ(idx + 1, buf_sv, maxlen);

if (n<=0) return n;

p = SvPV_force_nolen(buf_sv);
end = p + SvCUR(buf_sv);
while (p < end) {
if (*p == 'o') *p = 'e';
p++;
}
return SvCUR(buf_sv);
}


XS(XS_XS__APItest__XSUB_XS_VERSION_undef); XS(XS_XS__APItest__XSUB_XS_VERSION_undef);
XS(XS_XS__APItest__XSUB_XS_VERSION_empty); XS(XS_XS__APItest__XSUB_XS_VERSION_empty);
XS(XS_XS__APItest__XSUB_XS_APIVERSION_invalid); XS(XS_XS__APItest__XSUB_XS_APIVERSION_invalid);
Expand Down Expand Up @@ -2750,6 +2770,11 @@ CODE:
PERL_UNUSED_VAR(items); PERL_UNUSED_VAR(items);
croak("postinc called as a function"); croak("postinc called as a function");


void
filter()
CODE:
filter_add(filter_call, NULL);

BOOT: BOOT:
{ {
CV *asscv = get_cv("XS::APItest::postinc", 0); CV *asscv = get_cv("XS::APItest::postinc", 0);
Expand Down
10 changes: 10 additions & 0 deletions ext/XS-APItest/t/eval-filter.t
@@ -0,0 +1,10 @@
#!perl -w
use strict;

use Test::More tests => 1;
use XS::APItest;

BEGIN { eval "BEGIN{ filter() }" }

is "foo", "fee", "evals share filters with the currently compiling scope";
# See [perl #87064].
2 changes: 1 addition & 1 deletion op.c
Expand Up @@ -4453,7 +4453,7 @@ Perl_vload_module(pTHX_ U32 flags, SV *name, SV *ver, va_list *args)


ENTER; ENTER;
SAVEVPTR(PL_curcop); SAVEVPTR(PL_curcop);
lex_start(NULL, NULL, 0); lex_start(NULL, NULL, LEX_START_SAME_FILTER);
utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
veop, modname, imop); veop, modname, imop);
LEAVE; LEAVE;
Expand Down
3 changes: 3 additions & 0 deletions parser.h
Expand Up @@ -112,6 +112,9 @@ typedef struct yy_parser {
/* flags for lexer API */ /* flags for lexer API */
#define LEX_STUFF_UTF8 0x00000001 #define LEX_STUFF_UTF8 0x00000001
#define LEX_KEEP_PREVIOUS 0x00000002 #define LEX_KEEP_PREVIOUS 0x00000002
#ifdef PERL_CORE
# define LEX_START_SAME_FILTER 0x00000001
#endif


/* flags for parser API */ /* flags for parser API */
#define PARSE_OPTIONAL 0x00000001 #define PARSE_OPTIONAL 0x00000001
Expand Down
4 changes: 2 additions & 2 deletions pp_ctl.c
Expand Up @@ -3090,7 +3090,7 @@ Perl_sv_compile_2op_is_broken(pTHX_ SV *sv, OP **startop, const char *code,
PERL_ARGS_ASSERT_SV_COMPILE_2OP_IS_BROKEN; PERL_ARGS_ASSERT_SV_COMPILE_2OP_IS_BROKEN;


ENTER_with_name("eval"); ENTER_with_name("eval");
lex_start(sv, NULL, 0); lex_start(sv, NULL, LEX_START_SAME_FILTER);
SAVETMPS; SAVETMPS;
/* switch to eval mode */ /* switch to eval mode */


Expand Down Expand Up @@ -3957,7 +3957,7 @@ PP(pp_entereval)
TAINT_PROPER("eval"); TAINT_PROPER("eval");


ENTER_with_name("eval"); ENTER_with_name("eval");
lex_start(sv, NULL, 0); lex_start(sv, NULL, LEX_START_SAME_FILTER);
SAVETMPS; SAVETMPS;


/* switch to eval mode */ /* switch to eval mode */
Expand Down
13 changes: 10 additions & 3 deletions toke.c
Expand Up @@ -667,19 +667,23 @@ code in I<line> comes first and must consist of complete lines of input,
and I<rsfp> supplies the remainder of the source. and I<rsfp> supplies the remainder of the source.
The I<flags> parameter is reserved for future use, and must always The I<flags> parameter is reserved for future use, and must always
be zero. be zero, except for one flag that is currently reserved for perl's internal
use.
=cut =cut
*/ */


/* LEX_START_SAME_FILTER indicates that this is not a new file, so it
can share filters with the current parser. */

void void
Perl_lex_start(pTHX_ SV *line, PerlIO *rsfp, U32 flags) Perl_lex_start(pTHX_ SV *line, PerlIO *rsfp, U32 flags)
{ {
dVAR; dVAR;
const char *s = NULL; const char *s = NULL;
STRLEN len; STRLEN len;
yy_parser *parser, *oparser; yy_parser *parser, *oparser;
if (flags) if (flags && flags != LEX_START_SAME_FILTER)
Perl_croak(aTHX_ "Lexing code internal error (%s)", "lex_start"); Perl_croak(aTHX_ "Lexing code internal error (%s)", "lex_start");


/* create and initialise a parser */ /* create and initialise a parser */
Expand Down Expand Up @@ -708,7 +712,10 @@ Perl_lex_start(pTHX_ SV *line, PerlIO *rsfp, U32 flags)
parser->lex_state = LEX_NORMAL; parser->lex_state = LEX_NORMAL;
parser->expect = XSTATE; parser->expect = XSTATE;
parser->rsfp = rsfp; parser->rsfp = rsfp;
parser->rsfp_filters = newAV(); parser->rsfp_filters =
!(flags & LEX_START_SAME_FILTER) || !oparser
? newAV()
: MUTABLE_AV(SvREFCNT_inc(oparser->rsfp_filters));


Newx(parser->lex_brackstack, 120, char); Newx(parser->lex_brackstack, 120, char);
Newx(parser->lex_casestack, 12, char); Newx(parser->lex_casestack, 12, char);
Expand Down

0 comments on commit 27fcb6e

Please sign in to comment.