From: Gurusamy Sarathy Date: Thu, 4 Nov 1999 17:28:29 +0000 (+0000) Subject: implement STOP blocks and fix compiler to use them (minimally X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=4f25aa189c4a92535547c706ad37c13b7caee387;p=p5sagit%2Fp5-mst-13.2.git implement STOP blocks and fix compiler to use them (minimally tested) p4raw-id: //depot/perl@4515 --- diff --git a/embedvar.h b/embedvar.h index 3795432..556e4d0 100644 --- a/embedvar.h +++ b/embedvar.h @@ -363,6 +363,7 @@ #define PL_statusvalue_vms (PERL_GET_INTERP->Istatusvalue_vms) #define PL_stderrgv (PERL_GET_INTERP->Istderrgv) #define PL_stdingv (PERL_GET_INTERP->Istdingv) +#define PL_stopav (PERL_GET_INTERP->Istopav) #define PL_strtab (PERL_GET_INTERP->Istrtab) #define PL_strtab_mutex (PERL_GET_INTERP->Istrtab_mutex) #define PL_sub_generation (PERL_GET_INTERP->Isub_generation) @@ -622,6 +623,7 @@ #define PL_statusvalue_vms (vTHX->Istatusvalue_vms) #define PL_stderrgv (vTHX->Istderrgv) #define PL_stdingv (vTHX->Istdingv) +#define PL_stopav (vTHX->Istopav) #define PL_strtab (vTHX->Istrtab) #define PL_strtab_mutex (vTHX->Istrtab_mutex) #define PL_sub_generation (vTHX->Isub_generation) @@ -883,6 +885,7 @@ #define PL_Istatusvalue_vms PL_statusvalue_vms #define PL_Istderrgv PL_stderrgv #define PL_Istdingv PL_stdingv +#define PL_Istopav PL_stopav #define PL_Istrtab PL_strtab #define PL_Istrtab_mutex PL_strtab_mutex #define PL_Isub_generation PL_sub_generation diff --git a/ext/B/B/Lint.pm b/ext/B/B/Lint.pm index 3a47142..41d3c5a 100644 --- a/ext/B/B/Lint.pm +++ b/ext/B/B/Lint.pm @@ -241,7 +241,7 @@ sub B::SVOP::lint { } if ($check{private_names}) { my $opname = $op->name; - if (($opname eq "gv" || $opname eq "gvsv") { + if ($opname eq "gv" || $opname eq "gvsv") { my $gv = $op->gv; if ($gv->NAME =~ /^_./ && $gv->STASH->NAME ne $curstash) { warning('Illegal reference to private name %s', $gv->NAME); diff --git a/ext/B/B/Stash.pm b/ext/B/B/Stash.pm index 828ffac..d992a89 100644 --- a/ext/B/B/Stash.pm +++ b/ext/B/B/Stash.pm @@ -4,7 +4,7 @@ package B::Stash; BEGIN { %Seen = %INC } -END { +STOP { my @arr=scan($main::{"main::"}); @arr=map{s/\:\:$//;$_;} @arr; print "-umain,-u", join (",-u",@arr) ,"\n"; diff --git a/ext/B/NOTES b/ext/B/NOTES index ee10ba0..8309892 100644 --- a/ext/B/NOTES +++ b/ext/B/NOTES @@ -161,8 +161,8 @@ O module it should return a sub ref (usually a closure) to perform the actual compilation. When O regains control, it ensures that the "-c" option is forced (so that the program being compiled doesn't - end up running) and registers an END block to call back the sub ref + end up running) and registers a STOP block to call back the sub ref returned from the backend's compile(). Perl then continues by parsing prog.pl (just as it would with "perl -c prog.pl") and after - doing so, assuming there are no parse-time errors, the END block + doing so, assuming there are no parse-time errors, the STOP block of O gets called and the actual backend compilation happens. Phew. diff --git a/ext/B/O.pm b/ext/B/O.pm index ad391a3..d07c4a5 100644 --- a/ext/B/O.pm +++ b/ext/B/O.pm @@ -11,7 +11,7 @@ sub import { my $compilesub = &{"B::${backend}::compile"}(@options); if (ref($compilesub) eq "CODE") { minus_c; - eval 'END { &$compilesub() }'; + eval 'STOP { &$compilesub() }'; } else { die $compilesub; } @@ -59,7 +59,7 @@ C module and calls the C function in that package, passing it OPTIONS. That function is expected to return a sub reference which we'll call CALLBACK. Next, the "compile-only" flag is switched on (equivalent to the command-line option C<-c>) -and an END block is registered which calls CALLBACK. Thus the main +and a STOP block is registered which calls CALLBACK. Thus the main Perl program mentioned on the command-line is read in, parsed and compiled into internal syntax tree form. Since the C<-c> flag is set, the program does not start running (excepting BEGIN blocks of diff --git a/intrpvar.h b/intrpvar.h index 24ff54e..9f6f3b2 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -92,6 +92,7 @@ PERLVAR(Iglobalstash, HV *) /* global keyword overrides imported here */ PERLVAR(Icurstname, SV *) /* name of current package */ PERLVAR(Ibeginav, AV *) /* names of BEGIN subroutines */ PERLVAR(Iendav, AV *) /* names of END subroutines */ +PERLVAR(Istopav, AV *) /* names of STOP subroutines */ PERLVAR(Iinitav, AV *) /* names of INIT subroutines */ PERLVAR(Istrtab, HV *) /* shared string table */ PERLVARI(Isub_generation,U32,1) /* incr to invalidate method cache */ diff --git a/keywords.h b/keywords.h index f6b98aa..972240f 100644 --- a/keywords.h +++ b/keywords.h @@ -16,236 +16,237 @@ #define KEY_LE 15 #define KEY_LT 16 #define KEY_NE 17 -#define KEY_abs 18 -#define KEY_accept 19 -#define KEY_alarm 20 -#define KEY_and 21 -#define KEY_atan2 22 -#define KEY_bind 23 -#define KEY_binmode 24 -#define KEY_bless 25 -#define KEY_caller 26 -#define KEY_chdir 27 -#define KEY_chmod 28 -#define KEY_chomp 29 -#define KEY_chop 30 -#define KEY_chown 31 -#define KEY_chr 32 -#define KEY_chroot 33 -#define KEY_close 34 -#define KEY_closedir 35 -#define KEY_cmp 36 -#define KEY_connect 37 -#define KEY_continue 38 -#define KEY_cos 39 -#define KEY_crypt 40 -#define KEY_dbmclose 41 -#define KEY_dbmopen 42 -#define KEY_defined 43 -#define KEY_delete 44 -#define KEY_die 45 -#define KEY_do 46 -#define KEY_dump 47 -#define KEY_each 48 -#define KEY_else 49 -#define KEY_elsif 50 -#define KEY_endgrent 51 -#define KEY_endhostent 52 -#define KEY_endnetent 53 -#define KEY_endprotoent 54 -#define KEY_endpwent 55 -#define KEY_endservent 56 -#define KEY_eof 57 -#define KEY_eq 58 -#define KEY_eval 59 -#define KEY_exec 60 -#define KEY_exists 61 -#define KEY_exit 62 -#define KEY_exp 63 -#define KEY_fcntl 64 -#define KEY_fileno 65 -#define KEY_flock 66 -#define KEY_for 67 -#define KEY_foreach 68 -#define KEY_fork 69 -#define KEY_format 70 -#define KEY_formline 71 -#define KEY_ge 72 -#define KEY_getc 73 -#define KEY_getgrent 74 -#define KEY_getgrgid 75 -#define KEY_getgrnam 76 -#define KEY_gethostbyaddr 77 -#define KEY_gethostbyname 78 -#define KEY_gethostent 79 -#define KEY_getlogin 80 -#define KEY_getnetbyaddr 81 -#define KEY_getnetbyname 82 -#define KEY_getnetent 83 -#define KEY_getpeername 84 -#define KEY_getpgrp 85 -#define KEY_getppid 86 -#define KEY_getpriority 87 -#define KEY_getprotobyname 88 -#define KEY_getprotobynumber 89 -#define KEY_getprotoent 90 -#define KEY_getpwent 91 -#define KEY_getpwnam 92 -#define KEY_getpwuid 93 -#define KEY_getservbyname 94 -#define KEY_getservbyport 95 -#define KEY_getservent 96 -#define KEY_getsockname 97 -#define KEY_getsockopt 98 -#define KEY_glob 99 -#define KEY_gmtime 100 -#define KEY_goto 101 -#define KEY_grep 102 -#define KEY_gt 103 -#define KEY_hex 104 -#define KEY_if 105 -#define KEY_index 106 -#define KEY_int 107 -#define KEY_ioctl 108 -#define KEY_join 109 -#define KEY_keys 110 -#define KEY_kill 111 -#define KEY_last 112 -#define KEY_lc 113 -#define KEY_lcfirst 114 -#define KEY_le 115 -#define KEY_length 116 -#define KEY_link 117 -#define KEY_listen 118 -#define KEY_local 119 -#define KEY_localtime 120 -#define KEY_lock 121 -#define KEY_log 122 -#define KEY_lstat 123 -#define KEY_lt 124 -#define KEY_m 125 -#define KEY_map 126 -#define KEY_mkdir 127 -#define KEY_msgctl 128 -#define KEY_msgget 129 -#define KEY_msgrcv 130 -#define KEY_msgsnd 131 -#define KEY_my 132 -#define KEY_ne 133 -#define KEY_next 134 -#define KEY_no 135 -#define KEY_not 136 -#define KEY_oct 137 -#define KEY_open 138 -#define KEY_opendir 139 -#define KEY_or 140 -#define KEY_ord 141 -#define KEY_our 142 -#define KEY_pack 143 -#define KEY_package 144 -#define KEY_pipe 145 -#define KEY_pop 146 -#define KEY_pos 147 -#define KEY_print 148 -#define KEY_printf 149 -#define KEY_prototype 150 -#define KEY_push 151 -#define KEY_q 152 -#define KEY_qq 153 -#define KEY_qr 154 -#define KEY_quotemeta 155 -#define KEY_qw 156 -#define KEY_qx 157 -#define KEY_rand 158 -#define KEY_read 159 -#define KEY_readdir 160 -#define KEY_readline 161 -#define KEY_readlink 162 -#define KEY_readpipe 163 -#define KEY_recv 164 -#define KEY_redo 165 -#define KEY_ref 166 -#define KEY_rename 167 -#define KEY_require 168 -#define KEY_reset 169 -#define KEY_return 170 -#define KEY_reverse 171 -#define KEY_rewinddir 172 -#define KEY_rindex 173 -#define KEY_rmdir 174 -#define KEY_s 175 -#define KEY_scalar 176 -#define KEY_seek 177 -#define KEY_seekdir 178 -#define KEY_select 179 -#define KEY_semctl 180 -#define KEY_semget 181 -#define KEY_semop 182 -#define KEY_send 183 -#define KEY_setgrent 184 -#define KEY_sethostent 185 -#define KEY_setnetent 186 -#define KEY_setpgrp 187 -#define KEY_setpriority 188 -#define KEY_setprotoent 189 -#define KEY_setpwent 190 -#define KEY_setservent 191 -#define KEY_setsockopt 192 -#define KEY_shift 193 -#define KEY_shmctl 194 -#define KEY_shmget 195 -#define KEY_shmread 196 -#define KEY_shmwrite 197 -#define KEY_shutdown 198 -#define KEY_sin 199 -#define KEY_sleep 200 -#define KEY_socket 201 -#define KEY_socketpair 202 -#define KEY_sort 203 -#define KEY_splice 204 -#define KEY_split 205 -#define KEY_sprintf 206 -#define KEY_sqrt 207 -#define KEY_srand 208 -#define KEY_stat 209 -#define KEY_study 210 -#define KEY_sub 211 -#define KEY_substr 212 -#define KEY_symlink 213 -#define KEY_syscall 214 -#define KEY_sysopen 215 -#define KEY_sysread 216 -#define KEY_sysseek 217 -#define KEY_system 218 -#define KEY_syswrite 219 -#define KEY_tell 220 -#define KEY_telldir 221 -#define KEY_tie 222 -#define KEY_tied 223 -#define KEY_time 224 -#define KEY_times 225 -#define KEY_tr 226 -#define KEY_truncate 227 -#define KEY_uc 228 -#define KEY_ucfirst 229 -#define KEY_umask 230 -#define KEY_undef 231 -#define KEY_unless 232 -#define KEY_unlink 233 -#define KEY_unpack 234 -#define KEY_unshift 235 -#define KEY_untie 236 -#define KEY_until 237 -#define KEY_use 238 -#define KEY_utime 239 -#define KEY_values 240 -#define KEY_vec 241 -#define KEY_wait 242 -#define KEY_waitpid 243 -#define KEY_wantarray 244 -#define KEY_warn 245 -#define KEY_while 246 -#define KEY_write 247 -#define KEY_x 248 -#define KEY_xor 249 -#define KEY_y 250 +#define KEY_STOP 18 +#define KEY_abs 19 +#define KEY_accept 20 +#define KEY_alarm 21 +#define KEY_and 22 +#define KEY_atan2 23 +#define KEY_bind 24 +#define KEY_binmode 25 +#define KEY_bless 26 +#define KEY_caller 27 +#define KEY_chdir 28 +#define KEY_chmod 29 +#define KEY_chomp 30 +#define KEY_chop 31 +#define KEY_chown 32 +#define KEY_chr 33 +#define KEY_chroot 34 +#define KEY_close 35 +#define KEY_closedir 36 +#define KEY_cmp 37 +#define KEY_connect 38 +#define KEY_continue 39 +#define KEY_cos 40 +#define KEY_crypt 41 +#define KEY_dbmclose 42 +#define KEY_dbmopen 43 +#define KEY_defined 44 +#define KEY_delete 45 +#define KEY_die 46 +#define KEY_do 47 +#define KEY_dump 48 +#define KEY_each 49 +#define KEY_else 50 +#define KEY_elsif 51 +#define KEY_endgrent 52 +#define KEY_endhostent 53 +#define KEY_endnetent 54 +#define KEY_endprotoent 55 +#define KEY_endpwent 56 +#define KEY_endservent 57 +#define KEY_eof 58 +#define KEY_eq 59 +#define KEY_eval 60 +#define KEY_exec 61 +#define KEY_exists 62 +#define KEY_exit 63 +#define KEY_exp 64 +#define KEY_fcntl 65 +#define KEY_fileno 66 +#define KEY_flock 67 +#define KEY_for 68 +#define KEY_foreach 69 +#define KEY_fork 70 +#define KEY_format 71 +#define KEY_formline 72 +#define KEY_ge 73 +#define KEY_getc 74 +#define KEY_getgrent 75 +#define KEY_getgrgid 76 +#define KEY_getgrnam 77 +#define KEY_gethostbyaddr 78 +#define KEY_gethostbyname 79 +#define KEY_gethostent 80 +#define KEY_getlogin 81 +#define KEY_getnetbyaddr 82 +#define KEY_getnetbyname 83 +#define KEY_getnetent 84 +#define KEY_getpeername 85 +#define KEY_getpgrp 86 +#define KEY_getppid 87 +#define KEY_getpriority 88 +#define KEY_getprotobyname 89 +#define KEY_getprotobynumber 90 +#define KEY_getprotoent 91 +#define KEY_getpwent 92 +#define KEY_getpwnam 93 +#define KEY_getpwuid 94 +#define KEY_getservbyname 95 +#define KEY_getservbyport 96 +#define KEY_getservent 97 +#define KEY_getsockname 98 +#define KEY_getsockopt 99 +#define KEY_glob 100 +#define KEY_gmtime 101 +#define KEY_goto 102 +#define KEY_grep 103 +#define KEY_gt 104 +#define KEY_hex 105 +#define KEY_if 106 +#define KEY_index 107 +#define KEY_int 108 +#define KEY_ioctl 109 +#define KEY_join 110 +#define KEY_keys 111 +#define KEY_kill 112 +#define KEY_last 113 +#define KEY_lc 114 +#define KEY_lcfirst 115 +#define KEY_le 116 +#define KEY_length 117 +#define KEY_link 118 +#define KEY_listen 119 +#define KEY_local 120 +#define KEY_localtime 121 +#define KEY_lock 122 +#define KEY_log 123 +#define KEY_lstat 124 +#define KEY_lt 125 +#define KEY_m 126 +#define KEY_map 127 +#define KEY_mkdir 128 +#define KEY_msgctl 129 +#define KEY_msgget 130 +#define KEY_msgrcv 131 +#define KEY_msgsnd 132 +#define KEY_my 133 +#define KEY_ne 134 +#define KEY_next 135 +#define KEY_no 136 +#define KEY_not 137 +#define KEY_oct 138 +#define KEY_open 139 +#define KEY_opendir 140 +#define KEY_or 141 +#define KEY_ord 142 +#define KEY_our 143 +#define KEY_pack 144 +#define KEY_package 145 +#define KEY_pipe 146 +#define KEY_pop 147 +#define KEY_pos 148 +#define KEY_print 149 +#define KEY_printf 150 +#define KEY_prototype 151 +#define KEY_push 152 +#define KEY_q 153 +#define KEY_qq 154 +#define KEY_qr 155 +#define KEY_quotemeta 156 +#define KEY_qw 157 +#define KEY_qx 158 +#define KEY_rand 159 +#define KEY_read 160 +#define KEY_readdir 161 +#define KEY_readline 162 +#define KEY_readlink 163 +#define KEY_readpipe 164 +#define KEY_recv 165 +#define KEY_redo 166 +#define KEY_ref 167 +#define KEY_rename 168 +#define KEY_require 169 +#define KEY_reset 170 +#define KEY_return 171 +#define KEY_reverse 172 +#define KEY_rewinddir 173 +#define KEY_rindex 174 +#define KEY_rmdir 175 +#define KEY_s 176 +#define KEY_scalar 177 +#define KEY_seek 178 +#define KEY_seekdir 179 +#define KEY_select 180 +#define KEY_semctl 181 +#define KEY_semget 182 +#define KEY_semop 183 +#define KEY_send 184 +#define KEY_setgrent 185 +#define KEY_sethostent 186 +#define KEY_setnetent 187 +#define KEY_setpgrp 188 +#define KEY_setpriority 189 +#define KEY_setprotoent 190 +#define KEY_setpwent 191 +#define KEY_setservent 192 +#define KEY_setsockopt 193 +#define KEY_shift 194 +#define KEY_shmctl 195 +#define KEY_shmget 196 +#define KEY_shmread 197 +#define KEY_shmwrite 198 +#define KEY_shutdown 199 +#define KEY_sin 200 +#define KEY_sleep 201 +#define KEY_socket 202 +#define KEY_socketpair 203 +#define KEY_sort 204 +#define KEY_splice 205 +#define KEY_split 206 +#define KEY_sprintf 207 +#define KEY_sqrt 208 +#define KEY_srand 209 +#define KEY_stat 210 +#define KEY_study 211 +#define KEY_sub 212 +#define KEY_substr 213 +#define KEY_symlink 214 +#define KEY_syscall 215 +#define KEY_sysopen 216 +#define KEY_sysread 217 +#define KEY_sysseek 218 +#define KEY_system 219 +#define KEY_syswrite 220 +#define KEY_tell 221 +#define KEY_telldir 222 +#define KEY_tie 223 +#define KEY_tied 224 +#define KEY_time 225 +#define KEY_times 226 +#define KEY_tr 227 +#define KEY_truncate 228 +#define KEY_uc 229 +#define KEY_ucfirst 230 +#define KEY_umask 231 +#define KEY_undef 232 +#define KEY_unless 233 +#define KEY_unlink 234 +#define KEY_unpack 235 +#define KEY_unshift 236 +#define KEY_untie 237 +#define KEY_until 238 +#define KEY_use 239 +#define KEY_utime 240 +#define KEY_values 241 +#define KEY_vec 242 +#define KEY_wait 243 +#define KEY_waitpid 244 +#define KEY_wantarray 245 +#define KEY_warn 246 +#define KEY_while 247 +#define KEY_write 248 +#define KEY_x 249 +#define KEY_xor 250 +#define KEY_y 251 diff --git a/keywords.pl b/keywords.pl index 438849a..acdf807 100755 --- a/keywords.pl +++ b/keywords.pl @@ -42,6 +42,7 @@ INIT LE LT NE +STOP abs accept alarm diff --git a/objXSUB.h b/objXSUB.h index 7b3a0a0..f7d1fd4 100644 --- a/objXSUB.h +++ b/objXSUB.h @@ -392,6 +392,8 @@ #define PL_stderrgv (*Perl_Istderrgv_ptr(aTHXo)) #undef PL_stdingv #define PL_stdingv (*Perl_Istdingv_ptr(aTHXo)) +#undef PL_stopav +#define PL_stopav (*Perl_Istopav_ptr(aTHXo)) #undef PL_strtab #define PL_strtab (*Perl_Istrtab_ptr(aTHXo)) #undef PL_strtab_mutex diff --git a/op.c b/op.c index cb868a4..6fd669a 100644 --- a/op.c +++ b/op.c @@ -4411,6 +4411,13 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) av_store(PL_endav, 0, (SV *)cv); GvCV(gv) = 0; } + else if (strEQ(s, "STOP") && !PL_error_count) { + if (!PL_stopav) + PL_stopav = newAV(); + av_unshift(PL_stopav, 1); + av_store(PL_stopav, 0, (SV *)cv); + GvCV(gv) = 0; + } else if (strEQ(s, "INIT") && !PL_error_count) { if (!PL_initav) PL_initav = newAV(); @@ -4522,6 +4529,13 @@ Perl_newXS(pTHX_ char *name, XSUBADDR_t subaddr, char *filename) av_store(PL_endav, 0, (SV *)cv); GvCV(gv) = 0; } + else if (strEQ(s, "STOP")) { + if (!PL_stopav) + PL_stopav = newAV(); + av_unshift(PL_stopav, 1); + av_store(PL_stopav, 0, (SV *)cv); + GvCV(gv) = 0; + } else if (strEQ(s, "INIT")) { if (!PL_initav) PL_initav = newAV(); diff --git a/perl.c b/perl.c index ce73fe9..6e907eb 100644 --- a/perl.c +++ b/perl.c @@ -433,9 +433,11 @@ perl_destruct(pTHXx) /* startup and shutdown function lists */ SvREFCNT_dec(PL_beginav); SvREFCNT_dec(PL_endav); + SvREFCNT_dec(PL_stopav); SvREFCNT_dec(PL_initav); PL_beginav = Nullav; PL_endav = Nullav; + PL_stopav = Nullav; PL_initav = Nullav; /* shortcuts just get cleared */ @@ -660,6 +662,8 @@ setuid perl scripts securely.\n"); env, xsinit); switch (ret) { case 0: + if (PL_stopav) + call_list(oldscope, PL_stopav); return 0; case 1: STATUS_ALL_FAILURE; @@ -670,8 +674,8 @@ setuid perl scripts securely.\n"); LEAVE; FREETMPS; PL_curstash = PL_defstash; - if (PL_endav && !PL_minus_c) - call_list(oldscope, PL_endav); + if (PL_stopav) + call_list(oldscope, PL_stopav); return STATUS_NATIVE_EXPORT; case 3: PerlIO_printf(Perl_error_log, "panic: top_env\n"); @@ -3075,7 +3079,11 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) if (paramList == PL_beginav) sv_catpv(atsv, "BEGIN failed--compilation aborted"); else - sv_catpv(atsv, "END failed--cleanup aborted"); + Perl_sv_catpvf(aTHX_ atsv, + "%s failed--call queue aborted", + paramList == PL_stopav ? "STOP" + : paramList == PL_initav ? "INIT" + : "END"); while (PL_scopestack_ix > oldscope) LEAVE; Perl_croak(aTHX_ "%s", SvPVX(atsv)); @@ -3090,15 +3098,16 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) LEAVE; FREETMPS; PL_curstash = PL_defstash; - if (PL_endav && !PL_minus_c) - call_list(oldscope, PL_endav); PL_curcop = &PL_compiling; PL_curcop->cop_line = oldline; if (PL_statusvalue) { if (paramList == PL_beginav) Perl_croak(aTHX_ "BEGIN failed--compilation aborted"); else - Perl_croak(aTHX_ "END failed--cleanup aborted"); + Perl_croak(aTHX_ "%s failed--call queue aborted", + paramList == PL_stopav ? "STOP" + : paramList == PL_initav ? "INIT" + : "END"); } my_exit_jump(); /* NOTREACHED */ diff --git a/pod/perldelta.pod b/pod/perldelta.pod index da1425e..e46df77 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -24,6 +24,12 @@ responsibility to ensure that warnings are enabled judiciously. =over 4 +=item STOP is a new keyword + +In addition to C, C and C, subroutines named +C are now special. They are queued up for execution at the +end of compilation, and cannot be called directly. + =item Treatment of list slices of undef has changed When taking a slice of a literal list (as opposed to a slice of @@ -603,6 +609,13 @@ BEGIN blocks are executed under such conditions, this variable enables perl code to determine whether actions that make sense only during normal running are warranted. See L. +=head2 STOP blocks + +Arbitrary code can be queued for execution when Perl has finished +parsing the program (i.e. when the compile phase ends) using STOP +blocks. These behave similar to END blocks, except for being +called at the end of compilation rather than at the end of execution. + =head2 Optional Y2K warnings If Perl is built with the cpp macro C defined, @@ -789,9 +802,7 @@ run in compile-only mode. Since this is typically not the expected behavior, END blocks are not executed anymore when the C<-c> switch is used. -Note that something resembling the previous behavior can still be -obtained by putting C at the very end of -the top level source file. +See L for how to run things when the compile phase ends. =head2 Potential to leak DATA filehandles diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 0b1f68e..277e634 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -1316,10 +1316,11 @@ ugly. Your code will be interpreted as an attempt to call a method named "elseif" for the class returned by the following block. This is unlikely to be what you want. -=item END failed--cleanup aborted +=item %s failed--call queue aborted -(F) An untrapped exception was raised while executing an END subroutine. -The interpreter is immediately exited. +(F) An untrapped exception was raised while executing a STOP, INIT, or +END subroutine. Processing of the remainder of the queue of such +routines has been prematurely ended. =item entering effective %s failed diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index f8efd7e..e061e29 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -3767,7 +3767,9 @@ array by 1 and moving everything down. If there are no elements in the array, returns the undefined value. If ARRAY is omitted, shifts the C<@_> array within the lexical scope of subroutines and formats, and the C<@ARGV> array at file scopes or within the lexical scopes established by -the C, C, C, and C constructs. +the C, C, C, C, and C +constructs. + See also C, C, and C. C and C do the same thing to the left end of an array that C and C do to the right end. diff --git a/pod/perlmod.pod b/pod/perlmod.pod index fc81fdf..45a82ad 100644 --- a/pod/perlmod.pod +++ b/pod/perlmod.pod @@ -213,8 +213,8 @@ This also has implications for the use of the SUPER:: qualifier =head2 Package Constructors and Destructors Three special subroutines act as package -constructors and destructors. These are the C, C, and -C routines. The C is optional for these routines. +constructors and destructors. These are the C, C, C, +and C routines. The C is optional for these routines. A C subroutine is executed as soon as possible, that is, the moment it is completely defined, even before the rest of the containing file @@ -225,24 +225,31 @@ files in time to be visible to the rest of the file. Once a C has run, it is immediately undefined and any code it used is returned to Perl's memory pool. This means you can't ever explicitly call a C. -Similar to C blocks, C blocks are run just before the -Perl runtime begins execution. For example, the code generators -documented in L make use of C blocks to initialize -and resolve pointers to XSUBs. - -An C subroutine is executed as late as possible, that is, when -the interpreter is being exited, even if it is exiting as a result of -a die() function. (But not if it's polymorphing into another program -via C, or being blown out of the water by a signal--you have to -trap that yourself (if you can).) You may have multiple C blocks -within a file--they will execute in reverse order of definition; that is: -last in, first out (LIFO). +An C subroutine is executed as late as possible, that is, after +perl has finished running the program and just before the interpreter +is being exited, even if it is exiting as a result of a die() function. +(But not if it's polymorphing into another program via C, or +being blown out of the water by a signal--you have to trap that yourself +(if you can).) You may have multiple C blocks within a file--they +will execute in reverse order of definition; that is: last in, first +out (LIFO). C blocks are not executed when you run perl with the +C<-c> switch. Inside an C subroutine, C<$?> contains the value that the program is going to pass to C. You can modify C<$?> to change the exit value of the program. Beware of changing C<$?> by accident (e.g. by running something via C). +Similar to C blocks, C blocks are run just before the +Perl runtime begins execution, in "first in, first out" (FIFO) order. +For example, the code generators documented in L make use of +C blocks to initialize and resolve pointers to XSUBs. + +Similar to C blocks, C blocks are run just after the +Perl compile phase ends and before the run time begins, in +LIFO order. C blocks are again useful in the Perl compiler +suite to save the compiled state of the program. + When you use the B<-n> and B<-p> switches to Perl, C and C work just as they do in B, as a degenerate case. As currently implemented (and subject to change, since its inconvenient at best), diff --git a/pod/perlrun.pod b/pod/perlrun.pod index 0c3fcad..8fec7c3 100644 --- a/pod/perlrun.pod +++ b/pod/perlrun.pod @@ -268,9 +268,10 @@ An alternate delimiter may be specified using B<-F>. =item B<-c> causes Perl to check the syntax of the program and then exit without -executing it. Actually, it I execute C, C, and C blocks, -because these are considered as occurring outside the execution of -your program. C blocks, however, will be skipped. +executing it. Actually, it I execute C, C, and +C blocks, because these are considered as occurring outside the +execution of your program. C and C blocks, however, will +be skipped. =item B<-d> diff --git a/pod/perlsub.pod b/pod/perlsub.pod index 4abdc39..416763f 100644 --- a/pod/perlsub.pod +++ b/pod/perlsub.pod @@ -207,9 +207,8 @@ core, as are modules whose names are in all lower case. A function in all capitals is a loosely-held convention meaning it will be called indirectly by the run-time system itself, usually due to a triggered event. Functions that do special, pre-defined -things include C, C, C, and C--plus -all functions mentioned in L. The 5.005 release adds -C to this list. +things include C, C, C, C, C, and +C--plus all functions mentioned in L. =head2 Private Variables via my() @@ -455,7 +454,7 @@ starts to run: } See L about the -special triggered functions, C and C. +special triggered functions, C, C, C and C. If declared at the outermost scope (the file scope), then lexicals work somewhat like C's file statics. They are available to all diff --git a/pod/perltodo.pod b/pod/perltodo.pod index 4b2ed48..7836acf 100644 --- a/pod/perltodo.pod +++ b/pod/perltodo.pod @@ -824,7 +824,8 @@ Workarounds to help Win32 dynamic loading. =head2 END blocks -END blocks need saving in compiled output. +END blocks need saving in compiled output, now that STOP blocks +are available. =head2 _AUTOLOAD diff --git a/toke.c b/toke.c index 253db35..019765b 100644 --- a/toke.c +++ b/toke.c @@ -3776,6 +3776,7 @@ Perl_yylex(pTHX) case KEY_DESTROY: case KEY_BEGIN: case KEY_END: + case KEY_STOP: case KEY_INIT: if (PL_expect == XSTATE) { s = PL_bufptr; @@ -5214,6 +5215,9 @@ Perl_keyword(pTHX_ register char *d, I32 len) break; } break; + case 'S': + if (strEQ(d,"STOP")) return KEY_STOP; + break; case 's': switch (d[1]) { case 0: return KEY_s;