summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embedvar.h3
-rw-r--r--ext/B/B/Lint.pm2
-rw-r--r--ext/B/B/Stash.pm2
-rw-r--r--ext/B/NOTES4
-rw-r--r--ext/B/O.pm4
-rw-r--r--intrpvar.h1
-rw-r--r--keywords.h467
-rwxr-xr-xkeywords.pl1
-rw-r--r--objXSUB.h2
-rw-r--r--op.c14
-rw-r--r--perl.c21
-rw-r--r--pod/perldelta.pod17
-rw-r--r--pod/perldiag.pod7
-rw-r--r--pod/perlfunc.pod4
-rw-r--r--pod/perlmod.pod35
-rw-r--r--pod/perlrun.pod7
-rw-r--r--pod/perlsub.pod7
-rw-r--r--pod/perltodo.pod3
-rw-r--r--toke.c4
19 files changed, 331 insertions, 274 deletions
diff --git a/embedvar.h b/embedvar.h
index 37954329dd..556e4d03ed 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 3a4714226e..41d3c5ae22 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 828ffac3c0..d992a89af8 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 ee10ba03e9..8309892d80 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 ad391a3f4a..d07c4a5b0f 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<B::Backend> module and calls the C<compile> 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 24ff54e803..9f6f3b2548 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 f6b98aa802..972240f4f8 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 438849a057..acdf807d43 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 7b3a0a064d..f7d1fd475a 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 cb868a4500..6fd669a7c6 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 ce73fe911e..6e907eb822 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 da1425e6c1..e46df77f83 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<BEGIN>, C<INIT> and C<END>, subroutines named
+C<STOP> 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<perlvar>.
+=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<PERL_Y2KWARN> 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<BEGIN { $^C = 0; exit; }> at the very end of
-the top level source file.
+See L<STOP blocks> 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 0b1f68e848..277e6342bc 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 f8efd7e428..e061e29c04 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<eval ''>, C<BEGIN {}>, C<END {}>, and C<INIT {}> constructs.
+the C<eval ''>, C<BEGIN {}>, C<INIT {}>, C<STOP {}>, and C<END {}>
+constructs.
+
See also C<unshift>, C<push>, and C<pop>. C<Shift()> and C<unshift> do the
same thing to the left end of an array that C<pop> and C<push> do to the
right end.
diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index fc81fdfaae..45a82ad7a2 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<BEGIN>, C<INIT>, and
-C<END> routines. The C<sub> is optional for these routines.
+constructors and destructors. These are the C<BEGIN>, C<STOP>, C<INIT>,
+and C<END> routines. The C<sub> is optional for these routines.
A C<BEGIN> 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<BEGIN>
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<BEGIN>.
-Similar to C<BEGIN> blocks, C<INIT> blocks are run just before the
-Perl runtime begins execution. For example, the code generators
-documented in L<perlcc> make use of C<INIT> blocks to initialize
-and resolve pointers to XSUBs.
-
-An C<END> 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<exec>, or being blown out of the water by a signal--you have to
-trap that yourself (if you can).) You may have multiple C<END> blocks
-within a file--they will execute in reverse order of definition; that is:
-last in, first out (LIFO).
+An C<END> 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<exec>, or
+being blown out of the water by a signal--you have to trap that yourself
+(if you can).) You may have multiple C<END> blocks within a file--they
+will execute in reverse order of definition; that is: last in, first
+out (LIFO). C<END> blocks are not executed when you run perl with the
+C<-c> switch.
Inside an C<END> subroutine, C<$?> contains the value that the program is
going to pass to C<exit()>. 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<system>).
+Similar to C<BEGIN> blocks, C<INIT> 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<perlcc> make use of
+C<INIT> blocks to initialize and resolve pointers to XSUBs.
+
+Similar to C<END> blocks, C<STOP> blocks are run just after the
+Perl compile phase ends and before the run time begins, in
+LIFO order. C<STOP> 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<BEGIN> and
C<END> work just as they do in B<awk>, 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 0c3fcad921..8fec7c397a 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<will> execute C<BEGIN>, C<END>, and C<use> blocks,
-because these are considered as occurring outside the execution of
-your program. C<INIT> blocks, however, will be skipped.
+executing it. Actually, it I<will> execute C<BEGIN>, C<STOP>, and
+C<use> blocks, because these are considered as occurring outside the
+execution of your program. C<INIT> and C<END> blocks, however, will
+be skipped.
=item B<-d>
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index 4abdc39529..416763f6d8 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<BEGIN>, C<END>, C<AUTOLOAD>, and C<DESTROY>--plus
-all functions mentioned in L<perltie>. The 5.005 release adds
-C<INIT> to this list.
+things include C<BEGIN>, C<STOP>, C<INIT>, C<END>, C<AUTOLOAD>, and
+C<DESTROY>--plus all functions mentioned in L<perltie>.
=head2 Private Variables via my()
@@ -455,7 +454,7 @@ starts to run:
}
See L<perlmod/"Package Constructors and Destructors"> about the
-special triggered functions, C<BEGIN> and C<INIT>.
+special triggered functions, C<BEGIN>, C<STOP>, C<INIT> and C<END>.
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 4b2ed48a09..7836acf677 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 253db354f4..019765b08c 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;