From: Nicholas Clark Date: Wed, 21 May 2008 09:18:00 +0000 (+0000) Subject: Eliminate POSIX::int_macro_int, and all the complex AUTOLOAD fandango X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e99d581a4aaa3c92d0b0dda6799157fe7a569f31;p=p5sagit%2Fp5-mst-13.2.git Eliminate POSIX::int_macro_int, and all the complex AUTOLOAD fandango that creates closures round it. Instead, wrap WEXITSTATUS, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WSTOPSIG and WTERMSIG directly with XS. The shared library is slightly larger, but dynamic memory usage savings beat this, even within one thread of one process. Simpler code too. p4raw-id: //depot/perl@33896 --- diff --git a/ext/B/t/concise-xs.t b/ext/B/t/concise-xs.t index 3906efe..cc31958 100644 --- a/ext/B/t/concise-xs.t +++ b/ext/B/t/concise-xs.t @@ -180,7 +180,13 @@ my $testpkgs = { skip => [qw/ _POSIX_JOB_CONTROL /, # platform varying # Might be XS or imported from Fcntl, depending on your # perl version: - qw / S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG /], + qw / S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG /, + # Might be XS or AUTOLOADed, depending on your perl + # version: + qw /WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED + WSTOPSIG WTERMSIG/, + 'int_macro_int', # Removed in POSIX 1.16 + ], perl => [qw/ import croak AUTOLOAD /], XS => [qw/ write wctomb wcstombs uname tzset tzname @@ -194,7 +200,7 @@ my $testpkgs = { mblen lseek log10 localeconv ldexp lchown isxdigit isupper isspace ispunct isprint islower isgraph isdigit iscntrl isalpha - isalnum int_macro_int getcwd frexp fpathconf + isalnum getcwd frexp fpathconf fmod floor dup2 dup difftime cuserid ctime ctermid cosh constant close clock ceil bootstrap atan asin asctime acos access abort diff --git a/ext/POSIX/POSIX.pm b/ext/POSIX/POSIX.pm index 2ceba9f..0a5553b 100644 --- a/ext/POSIX/POSIX.pm +++ b/ext/POSIX/POSIX.pm @@ -4,7 +4,7 @@ use warnings; our(@ISA, %EXPORT_TAGS, @EXPORT_OK, @EXPORT, $AUTOLOAD, %SIGRT) = (); -our $VERSION = "1.15"; +our $VERSION = "1.16"; use AutoLoader; @@ -35,10 +35,6 @@ sub usage; XSLoader::load 'POSIX', $VERSION; -my %NON_CONSTS - = (map {($_,1)} qw(WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED WSTOPSIG - WTERMSIG)); - sub AUTOLOAD { no strict; no warnings 'uninitialized'; @@ -50,15 +46,9 @@ sub AUTOLOAD { local $! = 0; my $constname = $AUTOLOAD; $constname =~ s/.*:://; - if ($NON_CONSTS{$constname}) { - my ($val, $error) = &int_macro_int($constname, $_[0]); - croak $error if $error; - *$AUTOLOAD = sub { &int_macro_int($constname, $_[0]) }; - } else { - my ($error, $val) = constant($constname); - croak $error if $error; - *$AUTOLOAD = sub { $val }; - } + my ($error, $val) = constant($constname); + croak $error if $error; + *$AUTOLOAD = sub { $val }; goto &$AUTOLOAD; } diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index b61b0a6..41d66a6 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -394,116 +394,6 @@ not_here(const char *s) #include "const-c.inc" -/* These were implemented in the old "constant" subroutine. They are actually - macros that take an integer argument and return an integer result. */ -static int -int_macro_int (const char *name, STRLEN len, IV *arg_result) { - /* Initially switch on the length of the name. */ - /* This code has been edited from a "constant" function generated by: - -use ExtUtils::Constant qw (constant_types C_constant XS_constant); - -my $types = {map {($_, 1)} qw(IV)}; -my @names = (qw(WEXITSTATUS WIFEXITED - WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG)); - -print constant_types(); # macro defs -foreach (C_constant ("POSIX", 'int_macro_int', 'IV', $types, undef, 5, @names) ) { - print $_, "\n"; # C constant subs -} -print "#### XS Section:\n"; -print XS_constant ("POSIX", $types); - */ - - switch (len) { - case 8: - /* Names all of length 8. */ - /* WSTOPSIG WTERMSIG */ - /* Offset 1 gives the best switch position. */ - switch (name[1]) { - case 'S': - if (memEQ(name, "WSTOPSIG", 8)) { - /* ^ */ -#ifdef WSTOPSIG - int i = *arg_result; - *arg_result = WSTOPSIG(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - case 'T': - if (memEQ(name, "WTERMSIG", 8)) { - /* ^ */ -#ifdef WTERMSIG - int i = *arg_result; - *arg_result = WTERMSIG(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - } - break; - case 9: - if (memEQ(name, "WIFEXITED", 9)) { -#ifdef WIFEXITED - int i = *arg_result; - *arg_result = WIFEXITED(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - case 10: - if (memEQ(name, "WIFSTOPPED", 10)) { -#ifdef WIFSTOPPED - int i = *arg_result; - *arg_result = WIFSTOPPED(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - case 11: - /* Names all of length 11. */ - /* WEXITSTATUS WIFSIGNALED */ - /* Offset 1 gives the best switch position. */ - switch (name[1]) { - case 'E': - if (memEQ(name, "WEXITSTATUS", 11)) { - /* ^ */ -#ifdef WEXITSTATUS - int i = *arg_result; - *arg_result = WEXITSTATUS(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - case 'I': - if (memEQ(name, "WIFSIGNALED", 11)) { - /* ^ */ -#ifdef WIFSIGNALED - int i = *arg_result; - *arg_result = WIFSIGNALED(WMUNGE(i)); - return PERL_constant_ISIV; -#else - return PERL_constant_NOTDEF; -#endif - } - break; - } - break; - } - return PERL_constant_NOTFOUND; -} - static void restore_sigmask(pTHX_ SV *osset_sv) { @@ -756,47 +646,29 @@ MODULE = POSIX PACKAGE = POSIX INCLUDE: const-xs.inc -void -int_macro_int(sv, iv) - PREINIT: - dXSTARG; - STRLEN len; - int type; - INPUT: - SV * sv; - const char * s = SvPV(sv, len); - IV iv; - PPCODE: - /* Change this to int_macro_int(s, len, &iv, &nv); - if you need to return both NVs and IVs */ - type = int_macro_int(s, len, &iv); - /* Return 1 or 2 items. First is error message, or undef if no error. - Second, if present, is found value */ - switch (type) { - case PERL_constant_NOTFOUND: - sv = sv_2mortal(newSVpvf("%s is not a valid POSIX macro", s)); - EXTEND(SP, 1); - PUSHs(&PL_sv_undef); - PUSHs(sv); - break; - case PERL_constant_NOTDEF: - sv = sv_2mortal(newSVpvf( - "Your vendor has not defined POSIX macro %s, used", s)); - EXTEND(SP, 1); - PUSHs(&PL_sv_undef); - PUSHs(sv); - break; - case PERL_constant_ISIV: - PUSHi(iv); - break; - default: - sv = sv_2mortal(newSVpvf( - "Unexpected return type %d while processing POSIX macro %s, used", - type, s)); - EXTEND(SP, 1); - PUSHs(&PL_sv_undef); - PUSHs(sv); - } +int +WEXITSTATUS(status) + int status + +int +WIFEXITED(status) + int status + +int +WIFSIGNALED(status) + int status + +int +WIFSTOPPED(status) + int status + +int +WSTOPSIG(status) + int status + +int +WTERMSIG(status) + int status int isalnum(charstring) diff --git a/pod/perltodo.pod b/pod/perltodo.pod index 6fe7a14..53158e7 100644 --- a/pod/perltodo.pod +++ b/pod/perltodo.pod @@ -551,18 +551,6 @@ These tasks would need C knowledge, and roughly the level of knowledge of the perl API that comes from writing modules that use XS to interface to C. -=head2 investigate removing int_macro_int from POSIX.xs - -As a hang over from the original C implementation, F -contains a function C which in conjunction with C is -used to wrap the C functions C, C, C, -C, C and C. It's probably worth replacing -this complexity with 5 simple direct wrappings of those 5 functions. - -However, it would be interesting if someone could measure the memory usage -before and after, both for the case of C and the case of -actually calling the Perl space functions. - =head2 safely supporting POSIX SA_SIGINFO Some years ago Jarkko supplied patches to provide support for the POSIX