Change 30292 by [EMAIL PROTECTED] on 2007/02/14 17:29:10
Integrate:
[ 28273]
Subject: [PATCH] literal string macros
From: Marcus Holland-Moritz <[EMAIL PROTECTED]>
Date: Mon, 22 May 2006 13:39:33 +0200
Message-ID: <[EMAIL PROTECTED]>
[ 29486]
No need to upgrade if all we're going to do is return.
[ 29872]
Given that we now do the tests in S_visit() to avoid calling the
helper function when skippable, no need to retain those tests
inside the helper functions do_clean_objs() and do_clean_named_objs().
[ 29983]
Neither gv_fetchpvn_flags() nor hv_fetch() need a NUL terminated
string, so don't bother allocating buffer space or adding a NUL.
[ 29987]
Convert the last remaining 256 byte "small"bufs to 128 bytes.
(The actual size doesn't matter, as the buffers are only there to
save a malloc() for the common, short, case. Coverage reports suggest
that we aren't actually testing the long case. Yet - will fix this)
[ 30000]
As we're not passing over (or copying in) a NUL, don't need that extra
byte for it, so correct the < to <= so that we use the smallbuf
whenever possible.
[ 30015]
Stop S_incline needing to temporarily write a '\0' into its passed-in
buffer. (Requires adding gv_fetchfile_flags(), savesharedpvn() and
CopFILE_setn() to provide pointer/length versions of APIs)
[ 30024]
A test to exercise the smallbuf overflow code in S_incline, and a
refactoring of that code to use only one 128 char array, not two.
[ 30064]
Add av_create_and_push() and av_create_and_unshift_one() to refactor
out two repeated idioms.
[ 30101]
A few more places where we know the length for sv_setpv() or sv_catpv()
[ 30229]
Un-TODO tests avec change #30228
Affected files ...
... //depot/maint-5.8/perl/av.c#42 integrate
... //depot/maint-5.8/perl/cop.h#36 integrate
... //depot/maint-5.8/perl/doio.c#104 integrate
... //depot/maint-5.8/perl/embed.fnc#209 integrate
... //depot/maint-5.8/perl/embed.h#157 integrate
... //depot/maint-5.8/perl/global.sym#60 integrate
... //depot/maint-5.8/perl/gv.c#99 integrate
... //depot/maint-5.8/perl/handy.h#49 integrate
... //depot/maint-5.8/perl/mg.c#149 integrate
... //depot/maint-5.8/perl/op.c#199 integrate
... //depot/maint-5.8/perl/perl.c#205 integrate
... //depot/maint-5.8/perl/pod/perlapi.pod#98 integrate
... //depot/maint-5.8/perl/pp_ctl.c#174 integrate
... //depot/maint-5.8/perl/proto.h#201 integrate
... //depot/maint-5.8/perl/sv.c#343 integrate
... //depot/maint-5.8/perl/t/comp/parser.t#18 integrate
... //depot/maint-5.8/perl/toke.c#166 integrate
... //depot/maint-5.8/perl/util.c#146 integrate
Differences ...
==== //depot/maint-5.8/perl/av.c#42 (text) ====
Index: perl/av.c
--- perl/av.c#41~29993~ 2007-01-26 01:15:17.000000000 -0800
+++ perl/av.c 2007-02-14 09:29:10.000000000 -0800
@@ -502,6 +502,24 @@
}
/*
+
+=for apidoc av_create_and_push
+
+Push an SV onto the end of the array, creating the array if necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+
+=cut
+*/
+
+void
+Perl_av_create_and_push(pTHX_ AV **const avp, SV *const val)
+{
+ if (!*avp)
+ *avp = newAV();
+ av_push(*avp, val);
+}
+
+/*
=for apidoc av_push
Pushes an SV onto the end of the array. The array will grow automatically
@@ -581,6 +599,26 @@
}
/*
+
+=for apidoc av_create_and_unshift_one
+
+Unshifts an SV onto the beginning of the array, creating the array if
+necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+
+=cut
+*/
+
+SV **
+Perl_av_create_and_unshift_one(pTHX_ AV **const avp, SV *const val)
+{
+ if (!*avp)
+ *avp = newAV();
+ av_unshift(*avp, 1);
+ return av_store(*avp, 0, val);
+}
+
+/*
=for apidoc av_unshift
Unshift the given number of C<undef> values onto the beginning of the
==== //depot/maint-5.8/perl/cop.h#36 (text) ====
Index: perl/cop.h
--- perl/cop.h#35~30290~ 2007-02-14 08:13:48.000000000 -0800
+++ perl/cop.h 2007-02-14 09:29:10.000000000 -0800
@@ -236,8 +236,10 @@
# ifdef NETWARE
# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv))
+# define CopFILE_setn(c,pv,l) ((c)->cop_file = savepv((pv),(l)))
# else
# define CopFILE_set(c,pv) ((c)->cop_file = savesharedpv(pv))
+# define CopFILE_setn(c,pv,l) ((c)->cop_file = savesharedpvn((pv),(l)))
# endif
# define CopFILESV(c) (CopFILE(c) \
@@ -268,6 +270,7 @@
# define CopFILEGV(c) ((c)->cop_filegv)
# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv))
# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
+# define CopFILE_setn(c,pv,l) CopFILEGV_set((c),
gv_fetchfile_flags((pv),(l),0))
# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL)
# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL)
# define CopFILEAVx(c) (GvAV(CopFILEGV(c)))
==== //depot/maint-5.8/perl/doio.c#104 (text) ====
Index: perl/doio.c
--- perl/doio.c#103~30058~ 2007-01-29 08:46:38.000000000 -0800
+++ perl/doio.c 2007-02-14 09:29:10.000000000 -0800
@@ -708,10 +708,9 @@
if (io && (IoFLAGS(io) & IOf_ARGV) && (IoFLAGS(io) & IOf_START)) {
IoFLAGS(io) &= ~IOf_START;
if (PL_inplace) {
- if (!PL_argvout_stack)
- PL_argvout_stack = newAV();
assert(PL_defoutgv);
- av_push(PL_argvout_stack, SvREFCNT_inc_simple_NN(PL_defoutgv));
+ Perl_av_create_and_push(aTHX_ &PL_argvout_stack,
+ SvREFCNT_inc_simple_NN(PL_defoutgv));
}
}
if (PL_filemode & (S_ISUID|S_ISGID)) {
==== //depot/maint-5.8/perl/embed.fnc#209 (text) ====
Index: perl/embed.fnc
--- perl/embed.fnc#208~30290~ 2007-02-14 08:13:48.000000000 -0800
+++ perl/embed.fnc 2007-02-14 09:29:10.000000000 -0800
@@ -114,11 +114,13 @@
ApdR |I32 |av_len |NN AV* ar
ApdR |AV* |av_make |I32 size|NN SV** svp
Apd |SV* |av_pop |NULLOK AV* ar
+ApdoxM |void |av_create_and_push|NN AV **const avp|NN SV *const val
Apd |void |av_push |NULLOK AV* ar|NN SV* val
p |void |av_reify |NN AV* ar
ApdR |SV* |av_shift |NULLOK AV* ar
Apd |SV** |av_store |NULLOK AV* ar|I32 key|NULLOK SV* val
Apd |void |av_undef |NULLOK AV* ar
+ApdoxM |SV** |av_create_and_unshift_one|NN AV **const avp|NN SV *const val
Apd |void |av_unshift |NULLOK AV* ar|I32 num
pR |OP* |bind_match |I32 type|NN OP* left|NN OP* pat
pR |OP* |block_end |I32 floor|NULLOK OP* seq
@@ -291,6 +293,8 @@
Apmb |void |gv_efullname3 |NN SV* sv|NN GV* gv|NULLOK const char* prefix
Ap |void |gv_efullname4 |NN SV* sv|NN GV* gv|NULLOK const char*
prefix|bool keepmain
Ap |GV* |gv_fetchfile |NN const char* name
+Ap |GV* |gv_fetchfile_flags|NN const char *const name|const STRLEN len\
+ |const U32 flags
Apd |GV* |gv_fetchmeth |NULLOK HV* stash|NN const char* name|STRLEN
len|I32 level
Apd |GV* |gv_fetchmeth_autoload |NULLOK HV* stash|NN const char*
name|STRLEN len|I32 level
Apdmb |GV* |gv_fetchmethod |NULLOK HV* stash|NN const char* name
@@ -682,6 +686,7 @@
Apda |char* |savepv |NULLOK const char* pv
Apda |char* |savepvn |NULLOK const char* pv|I32 len
Apda |char* |savesharedpv |NULLOK const char* pv
+Apda |char* |savesharedpvn |NN const char *const pv|const STRLEN len
Ap |void |savestack_grow
Ap |void |savestack_grow_cnt |I32 need
Ap |void |save_aelem |NN AV* av|I32 idx|NN SV **sptr
@@ -1378,7 +1383,7 @@
s |void |checkcomma |NN const char *s|NN const char *name \
|NN const char *what
s |void |force_ident |NN const char *s|int kind
-s |void |incline |NN char *s
+s |void |incline |NN const char *s
s |int |intuit_method |NN char *s|NULLOK GV *gv|NULLOK CV *cv
s |int |intuit_more |NN char *s
s |I32 |lop |I32 f|int x|NN char *s
==== //depot/maint-5.8/perl/embed.h#157 (text+w) ====
Index: perl/embed.h
--- perl/embed.h#156~30290~ 2007-02-14 08:13:48.000000000 -0800
+++ perl/embed.h 2007-02-14 09:29:10.000000000 -0800
@@ -284,6 +284,7 @@
#define gv_efullname Perl_gv_efullname
#define gv_efullname4 Perl_gv_efullname4
#define gv_fetchfile Perl_gv_fetchfile
+#define gv_fetchfile_flags Perl_gv_fetchfile_flags
#define gv_fetchmeth Perl_gv_fetchmeth
#define gv_fetchmeth_autoload Perl_gv_fetchmeth_autoload
#define gv_fetchmethod_autoload Perl_gv_fetchmethod_autoload
@@ -710,6 +711,7 @@
#define savepv Perl_savepv
#define savepvn Perl_savepvn
#define savesharedpv Perl_savesharedpv
+#define savesharedpvn Perl_savesharedpvn
#define savestack_grow Perl_savestack_grow
#define savestack_grow_cnt Perl_savestack_grow_cnt
#define save_aelem Perl_save_aelem
@@ -2386,6 +2388,7 @@
#define gv_efullname(a,b) Perl_gv_efullname(aTHX_ a,b)
#define gv_efullname4(a,b,c,d) Perl_gv_efullname4(aTHX_ a,b,c,d)
#define gv_fetchfile(a) Perl_gv_fetchfile(aTHX_ a)
+#define gv_fetchfile_flags(a,b,c) Perl_gv_fetchfile_flags(aTHX_ a,b,c)
#define gv_fetchmeth(a,b,c,d) Perl_gv_fetchmeth(aTHX_ a,b,c,d)
#define gv_fetchmeth_autoload(a,b,c,d) Perl_gv_fetchmeth_autoload(aTHX_
a,b,c,d)
#define gv_fetchmethod_autoload(a,b,c) Perl_gv_fetchmethod_autoload(aTHX_
a,b,c)
@@ -2810,6 +2813,7 @@
#define savepv(a) Perl_savepv(aTHX_ a)
#define savepvn(a,b) Perl_savepvn(aTHX_ a,b)
#define savesharedpv(a) Perl_savesharedpv(aTHX_ a)
+#define savesharedpvn(a,b) Perl_savesharedpvn(aTHX_ a,b)
#define savestack_grow() Perl_savestack_grow(aTHX)
#define savestack_grow_cnt(a) Perl_savestack_grow_cnt(aTHX_ a)
#define save_aelem(a,b,c) Perl_save_aelem(aTHX_ a,b,c)
==== //depot/maint-5.8/perl/global.sym#60 (text+w) ====
Index: perl/global.sym
--- perl/global.sym#59~30181~ 2007-02-09 09:20:56.000000000 -0800
+++ perl/global.sym 2007-02-14 09:29:10.000000000 -0800
@@ -139,6 +139,7 @@
Perl_gv_efullname3
Perl_gv_efullname4
Perl_gv_fetchfile
+Perl_gv_fetchfile_flags
Perl_gv_fetchmeth
Perl_gv_fetchmeth_autoload
Perl_gv_fetchmethod
@@ -386,6 +387,7 @@
Perl_savepv
Perl_savepvn
Perl_savesharedpv
+Perl_savesharedpvn
Perl_savestack_grow
Perl_savestack_grow_cnt
Perl_save_aelem
==== //depot/maint-5.8/perl/gv.c#99 (text) ====
Index: perl/gv.c
--- perl/gv.c#98~30110~ 2007-02-03 11:00:21.000000000 -0800
+++ perl/gv.c 2007-02-14 09:29:10.000000000 -0800
@@ -103,30 +103,38 @@
GV *
Perl_gv_fetchfile(pTHX_ const char *name)
{
- char smallbuf[256];
+ return gv_fetchfile_flags(name, strlen(name), 0);
+}
+
+GV *
+Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen,
+ const U32 flags)
+{
+ char smallbuf[128];
char *tmpbuf;
- STRLEN tmplen;
+ const STRLEN tmplen = namelen + 2;
GV *gv;
+ PERL_UNUSED_ARG(flags);
+
if (!PL_defstash)
return NULL;
- tmplen = strlen(name) + 2;
- if (tmplen < sizeof smallbuf)
+ if (tmplen <= sizeof smallbuf)
tmpbuf = smallbuf;
else
- Newx(tmpbuf, tmplen + 1, char);
+ Newx(tmpbuf, tmplen, char);
/* This is where the debugger's %{"::_<$filename"} hash is created */
tmpbuf[0] = '_';
tmpbuf[1] = '<';
- memcpy(tmpbuf + 2, name, tmplen - 1);
+ memcpy(tmpbuf + 2, name, namelen);
gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE);
if (!isGV(gv)) {
gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
#ifdef PERL_DONT_CREATE_GVSV
- GvSV(gv) = newSVpvn(name, tmplen - 2);
+ GvSV(gv) = newSVpvn(name, namelen);
#else
- sv_setpvn(GvSV(gv), name, tmplen - 2);
+ sv_setpvn(GvSV(gv), name, namelen);
#endif
if (PERLDB_LINE)
hv_magic(GvHVn(gv_AVadd(gv)), NULL, PERL_MAGIC_dbfile);
@@ -713,14 +721,13 @@
HV *stash;
GV *tmpgv;
- if (namelen + 3 < sizeof smallbuf)
+ if (namelen + 2 <= sizeof smallbuf)
tmpbuf = smallbuf;
else
- Newx(tmpbuf, namelen + 3, char);
+ Newx(tmpbuf, namelen + 2, char);
Copy(name,tmpbuf,namelen,char);
tmpbuf[namelen++] = ':';
tmpbuf[namelen++] = ':';
- tmpbuf[namelen] = '\0';
tmpgv = gv_fetchpvn_flags(tmpbuf, namelen, create, SVt_PVHV);
if (tmpbuf != smallbuf)
Safefree(tmpbuf);
@@ -808,14 +815,13 @@
char smallbuf[128];
char *tmpbuf;
- if (len + 3 < (I32)sizeof (smallbuf))
+ if (len + 2 <= (I32)sizeof (smallbuf))
tmpbuf = smallbuf;
else
- Newx(tmpbuf, len+3, char);
+ Newx(tmpbuf, len+2, char);
Copy(name, tmpbuf, len, char);
tmpbuf[len++] = ':';
tmpbuf[len++] = ':';
- tmpbuf[len] = '\0';
gvp = (GV**)hv_fetch(stash,tmpbuf,len,add);
gv = gvp ? *gvp : NULL;
if (gv && gv != (GV*)&PL_sv_undef) {
==== //depot/maint-5.8/perl/handy.h#49 (text) ====
Index: perl/handy.h
--- perl/handy.h#48~30261~ 2007-02-13 09:58:37.000000000 -0800
+++ perl/handy.h 2007-02-14 09:29:10.000000000 -0800
@@ -236,6 +236,44 @@
#define Ctl(ch) ((ch) & 037)
+/*
+=head1 SV-Body Allocation
+
+=for apidoc Ama|SV*|newSVpvs|const char* s
+Like C<newSVpvn>, but takes a literal string instead of a string/length pair.
+
+=for apidoc Ama|SV*|newSVpvs_share|const char* s
+Like C<newSVpvn_share>, but takes a literal string instead of a string/length
+pair and omits the hash parameter.
+
+=for apidoc Am|SV*|sv_catpvs|SV* sv|const char* s
+Like C<sv_catpvn>, but takes a literal string instead of a string/length pair.
+
+=for apidoc Am|SV*|sv_setpvs|SV* sv|const char* s
+Like C<sv_setpvn>, but takes a literal string instead of a string/length pair.
+
+=head1 Memory Management
+
+=for apidoc Ama|char*|savepvs|const char* s
+Like C<savepvn>, but takes a literal string instead of a string/length pair.
+
+=head1 GV Functions
+
+=for apidoc Am|HV*|gv_stashpvs|const char* name|I32 create
+Like C<gv_stashpvn>, but takes a literal string instead of a string/length
pair.
+
+=head1 Hash Manipulation Functions
+
+=for apidoc Am|SV**|hv_fetchs|HV* tb|const char* key|I32 lval
+Like C<hv_fetch>, but takes a literal string instead of a string/length pair.
+
+=for apidoc Am|SV**|hv_stores|HV* tb|const char* key|NULLOK SV* val
+Like C<hv_store>, but takes a literal string instead of a string/length pair
+and omits the hash parameter.
+
+=cut
+*/
+
/* concatenating with "" ensures that only literal strings are accepted as
argument */
#define STR_WITH_LEN(s) (s ""), (sizeof(s)-1)
@@ -248,10 +286,12 @@
#define newSVpvs(str) Perl_newSVpvn(aTHX_ STR_WITH_LEN(str))
#define newSVpvs_share(str) Perl_newSVpvn_share(aTHX_ STR_WITH_LEN(str), 0)
#define sv_catpvs(sv, str) Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str),
SV_GMAGIC)
+#define sv_setpvs(sv, str) Perl_sv_setpvn(aTHX_ sv, STR_WITH_LEN(str))
#define savepvs(str) Perl_savepvn(aTHX_ STR_WITH_LEN(str))
#define gv_stashpvs(str, create) Perl_gv_stashpvn(aTHX_ STR_WITH_LEN(str),
create)
#define gv_fetchpvs(namebeg, add, sv_type) Perl_gv_fetchpvn_flags(aTHX_
STR_WITH_LEN(namebeg), add, sv_type)
#define hv_fetchs(hv,key,lval) Perl_hv_fetch(aTHX_ hv, STR_WITH_LEN(key), lval)
+#define hv_stores(hv,key,val) Perl_hv_store(aTHX_ hv, STR_WITH_LEN(key), val,
0)
/*
==== //depot/maint-5.8/perl/mg.c#149 (text) ====
Index: perl/mg.c
--- perl/mg.c#148~30232~ 2007-02-12 08:27:14.000000000 -0800
+++ perl/mg.c 2007-02-14 09:29:10.000000000 -0800
@@ -1238,7 +1238,7 @@
#endif
/* cache state so we don't fetch it again */
if(sigstate == (Sighandler_t) SIG_IGN)
- sv_setpv(sv,"IGNORE");
+ sv_setpvs(sv,"IGNORE");
else
sv_setsv(sv,&PL_sv_undef);
PL_psig_ptr[i] = SvREFCNT_inc_simple_NN(sv);
==== //depot/maint-5.8/perl/op.c#199 (text) ====
Index: perl/op.c
--- perl/op.c#198~30291~ 2007-02-14 08:37:49.000000000 -0800
+++ perl/op.c 2007-02-14 09:29:10.000000000 -0800
@@ -4214,7 +4214,7 @@
if (gv)
gv_efullname3(name = sv_newmortal(), (GV *)gv, NULL);
- sv_setpv(msg, "Prototype mismatch:");
+ sv_setpvs(msg, "Prototype mismatch:");
if (name)
Perl_sv_catpvf(aTHX_ msg, " sub %"SVf, (void*)name);
if (SvPOK(cv))
@@ -4641,10 +4641,8 @@
SAVECOPFILE(&PL_compiling);
SAVECOPLINE(&PL_compiling);
- if (!PL_beginav)
- PL_beginav = newAV();
DEBUG_x( dump_sub(gv) );
- av_push(PL_beginav, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_beginav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
call_list(oldscope, PL_beginav);
@@ -4653,30 +4651,22 @@
LEAVE;
}
else if (strEQ(s, "END") && !PL_error_count) {
- if (!PL_endav)
- PL_endav = newAV();
DEBUG_x( dump_sub(gv) );
- av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, (SV*)cv);
+ Perl_av_create_and_unshift_one(aTHX_ &PL_endav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "CHECK") && !PL_error_count) {
- if (!PL_checkav)
- PL_checkav = newAV();
DEBUG_x( dump_sub(gv) );
if (PL_main_start && ckWARN(WARN_VOID))
Perl_warner(aTHX_ packWARN(WARN_VOID), "Too late to run CHECK
block");
- av_unshift(PL_checkav, 1);
- av_store(PL_checkav, 0, (SV*)cv);
+ Perl_av_create_and_unshift_one(aTHX_ &PL_checkav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "INIT") && !PL_error_count) {
- if (!PL_initav)
- PL_initav = newAV();
DEBUG_x( dump_sub(gv) );
if (PL_main_start && ckWARN(WARN_VOID))
Perl_warner(aTHX_ packWARN(WARN_VOID), "Too late to run INIT
block");
- av_push(PL_initav, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_initav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
}
@@ -4872,33 +4862,23 @@
goto done;
if (strEQ(s, "BEGIN")) {
- if (!PL_beginav)
- PL_beginav = newAV();
- av_push(PL_beginav, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_beginav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "END")) {
- if (!PL_endav)
- PL_endav = newAV();
- av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, (SV*)cv);
+ Perl_av_create_and_unshift_one(aTHX_ &PL_endav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "CHECK")) {
- if (!PL_checkav)
- PL_checkav = newAV();
if (PL_main_start && ckWARN(WARN_VOID))
Perl_warner(aTHX_ packWARN(WARN_VOID), "Too late to run CHECK
block");
- av_unshift(PL_checkav, 1);
- av_store(PL_checkav, 0, (SV*)cv);
+ Perl_av_create_and_unshift_one(aTHX_ &PL_checkav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "INIT")) {
- if (!PL_initav)
- PL_initav = newAV();
if (PL_main_start && ckWARN(WARN_VOID))
Perl_warner(aTHX_ packWARN(WARN_VOID), "Too late to run INIT
block");
- av_push(PL_initav, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_initav, (SV*)cv);
GvCV(gv) = 0; /* cv has been hijacked */
}
}
==== //depot/maint-5.8/perl/perl.c#205 (text) ====
Index: perl/perl.c
--- perl/perl.c#204~30291~ 2007-02-14 08:37:49.000000000 -0800
+++ perl/perl.c 2007-02-14 09:29:10.000000000 -0800
@@ -367,8 +367,8 @@
sv_setpvn(PERL_DEBUG_PAD(1), "", 0); /* ext/re needs these */
sv_setpvn(PERL_DEBUG_PAD(2), "", 0); /* even without DEBUGGING. */
#ifdef USE_ITHREADS
- PL_regex_padav = newAV();
- av_push(PL_regex_padav,(SV*)newAV()); /* First entry is an array of
empty elements */
+ /* First entry is an array of empty elements */
+ Perl_av_create_and_push(aTHX_ &PL_regex_padav,(SV*)newAV());
PL_regex_pad = AvARRAY(PL_regex_padav);
#endif
#ifdef USE_REENTRANT_API
@@ -1870,10 +1870,7 @@
{
SV *opts_prog;
- if (!PL_preambleav)
- PL_preambleav = newAV();
- av_push(PL_preambleav,
- newSVpvs("use Config;"));
+ Perl_av_create_and_push(aTHX_ &PL_preambleav, newSVpvs("use
Config;"));
if (*++s != ':') {
STRLEN opts;
@@ -2134,10 +2131,8 @@
#ifdef USE_SITECUSTOMIZE
if (!minus_f) {
- if (!PL_preambleav)
- PL_preambleav = newAV();
- av_unshift(PL_preambleav, 1);
- (void)av_store(PL_preambleav, 0, Perl_newSVpvf(aTHX_ "BEGIN { do
'%s/sitecustomize.pl' }", SITELIB_EXP));
+ (void)Perl_av_create_and_unshift_one(aTHX_ &PL_preambleav,
+ Perl_newSVpvf(aTHX_ "BEGIN { do
'%s/sitecustomize.pl' }", SITELIB_EXP));
}
#endif
@@ -3328,9 +3323,7 @@
sv_catpvs(sv, "\0)");
}
s += strlen(s);
- if (!PL_preambleav)
- PL_preambleav = newAV();
- av_push(PL_preambleav, sv);
+ Perl_av_create_and_push(aTHX_ &PL_preambleav, sv);
}
else
Perl_croak(aTHX_ "Missing argument to -%c", *(s-1));
@@ -5274,15 +5267,11 @@
if (PL_savebegin) {
if (paramList == PL_beginav) {
/* save PL_beginav for compiler */
- if (! PL_beginav_save)
- PL_beginav_save = newAV();
- av_push(PL_beginav_save, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_beginav_save, (SV*)cv);
}
else if (paramList == PL_checkav) {
/* save PL_checkav for compiler */
- if (! PL_checkav_save)
- PL_checkav_save = newAV();
- av_push(PL_checkav_save, (SV*)cv);
+ Perl_av_create_and_push(aTHX_ &PL_checkav_save, (SV*)cv);
}
} else {
SAVEFREESV(cv);
==== //depot/maint-5.8/perl/pod/perlapi.pod#98 (text+w) ====
Index: perl/pod/perlapi.pod
--- perl/pod/perlapi.pod#97~30290~ 2007-02-14 08:13:48.000000000 -0800
+++ perl/pod/perlapi.pod 2007-02-14 09:29:10.000000000 -0800
@@ -1348,6 +1348,16 @@
=for hackers
Found in file gv.c
+=item gv_stashpvs
+X<gv_stashpvs>
+
+Like C<gv_stashpvn>, but takes a literal string instead of a string/length
pair.
+
+ HV* gv_stashpvs(const char* name, I32 create)
+
+=for hackers
+Found in file handy.h
+
=item gv_stashsv
X<gv_stashsv>
@@ -1647,6 +1657,16 @@
=for hackers
Found in file hv.c
+=item hv_fetchs
+X<hv_fetchs>
+
+Like C<hv_fetch>, but takes a literal string instead of a string/length pair.
+
+ SV** hv_fetchs(HV* tb, const char* key, I32 lval)
+
+=for hackers
+Found in file handy.h
+
=item hv_fetch_ent
X<hv_fetch_ent>
@@ -1814,6 +1834,17 @@
=for hackers
Found in file hv.c
+=item hv_stores
+X<hv_stores>
+
+Like C<hv_store>, but takes a literal string instead of a string/length pair
+and omits the hash parameter.
+
+ SV** hv_stores(HV* tb, const char* key, NULLOK SV* val)
+
+=for hackers
+Found in file handy.h
+
=item hv_store_ent
X<hv_store_ent>
@@ -2238,6 +2269,16 @@
=for hackers
Found in file util.c
+=item savepvs
+X<savepvs>
+
+Like C<savepvn>, but takes a literal string instead of a string/length pair.
+
+ char* savepvs(const char* s)
+
+=for hackers
+Found in file handy.h
+
=item savesharedpv
X<savesharedpv>
@@ -2249,6 +2290,18 @@
=for hackers
Found in file util.c
+=item savesharedpvn
+X<savesharedpvn>
+
+A version of C<savepvn()> which allocates the duplicate string in memory
+which is shared between threads. (With the specific difference that a NULL
+pointer is not acceptable)
+
+ char* savesharedpvn(const char *const pv, const STRLEN len)
+
+=for hackers
+Found in file util.c
+
=item savesvpv
X<savesvpv>
@@ -4181,6 +4234,9 @@
Increments the reference count of the given SV.
+All of the following SvREFCNT_inc* macros are optimized versions of
+SvREFCNT_inc, and can be replaced with SvREFCNT_inc.
+
SV* SvREFCNT_inc(SV* sv)
=for hackers
@@ -4233,6 +4289,19 @@
=for hackers
Found in file sv.h
+=item SvREFCNT_inc_simple_void_NN
+X<SvREFCNT_inc_simple_void_NN>
+
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL. The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
+
+ SV* SvREFCNT_inc_simple_void_NN(SV* sv)
+
+=for hackers
+Found in file sv.h
+
=item SvREFCNT_inc_void
X<SvREFCNT_inc_void>
@@ -4688,6 +4757,27 @@
=for hackers
Found in file sv.c
+=item newSVpvs
+X<newSVpvs>
+
+Like C<newSVpvn>, but takes a literal string instead of a string/length pair.
+
+ SV* newSVpvs(const char* s)
+
+=for hackers
+Found in file handy.h
+
+=item newSVpvs_share
+X<newSVpvs_share>
+
+Like C<newSVpvn_share>, but takes a literal string instead of a string/length
+pair and omits the hash parameter.
+
+ SV* newSVpvs_share(const char* s)
+
+=for hackers
+Found in file handy.h
+
=item newSVrv
X<newSVrv>
@@ -4938,6 +5028,16 @@
=for hackers
Found in file sv.c
+=item sv_catpvs
+X<sv_catpvs>
+
+Like C<sv_catpvn>, but takes a literal string instead of a string/length pair.
+
+ SV* sv_catpvs(SV* sv, const char* s)
+
+=for hackers
+Found in file handy.h
+
=item sv_catpv_mg
X<sv_catpv_mg>
@@ -5515,6 +5615,16 @@
=for hackers
Found in file sv.c
+=item sv_setpvs
+X<sv_setpvs>
+
+Like C<sv_setpvn>, but takes a literal string instead of a string/length pair.
+
+ SV* sv_setpvs(SV* sv, const char* s)
+
+=for hackers
+Found in file handy.h
+
=item sv_setpv_mg
X<sv_setpv_mg>
==== //depot/maint-5.8/perl/pp_ctl.c#174 (text) ====
Index: perl/pp_ctl.c
--- perl/pp_ctl.c#173~30241~ 2007-02-12 12:43:49.000000000 -0800
+++ perl/pp_ctl.c 2007-02-14 09:29:10.000000000 -0800
@@ -2849,7 +2849,7 @@
}
else {
if (!*msg) {
- sv_setpv(ERRSV, "Compilation error");
+ sv_setpvs(ERRSV, "Compilation error");
}
}
#ifdef USE_5005THREADS
==== //depot/maint-5.8/perl/proto.h#201 (text+w) ====
Index: perl/proto.h
--- perl/proto.h#200~30290~ 2007-02-14 08:13:48.000000000 -0800
+++ perl/proto.h 2007-02-14 09:29:10.000000000 -0800
@@ -103,12 +103,14 @@
PERL_CALLCONV SV* Perl_av_pop(pTHX_ AV* ar);
PERL_CALLCONV void Perl_av_push(pTHX_ AV* ar, SV* val);
+PERL_CALLCONV void Perl_av_create_and_push(pTHX_ AV **const avp, SV *const
val);
PERL_CALLCONV void Perl_av_reify(pTHX_ AV* ar);
PERL_CALLCONV SV* Perl_av_shift(pTHX_ AV* ar)
__attribute__warn_unused_result__;
PERL_CALLCONV SV** Perl_av_store(pTHX_ AV* ar, I32 key, SV* val);
PERL_CALLCONV void Perl_av_undef(pTHX_ AV* ar);
+PERL_CALLCONV SV** Perl_av_create_and_unshift_one(pTHX_ AV **const avp, SV
*const val);
PERL_CALLCONV void Perl_av_unshift(pTHX_ AV* ar, I32 num);
PERL_CALLCONV OP* Perl_bind_match(pTHX_ I32 type, OP* left, OP* pat)
__attribute__warn_unused_result__;
@@ -368,6 +370,7 @@
/* PERL_CALLCONV void Perl_gv_efullname3(pTHX_ SV* sv, GV* gv, const char*
prefix); */
PERL_CALLCONV void Perl_gv_efullname4(pTHX_ SV* sv, GV* gv, const char*
prefix, bool keepmain);
PERL_CALLCONV GV* Perl_gv_fetchfile(pTHX_ const char* name);
+PERL_CALLCONV GV* Perl_gv_fetchfile_flags(pTHX_ const char *const name,
const STRLEN len, const U32 flags);
PERL_CALLCONV GV* Perl_gv_fetchmeth(pTHX_ HV* stash, const char* name,
STRLEN len, I32 level);
PERL_CALLCONV GV* Perl_gv_fetchmeth_autoload(pTHX_ HV* stash, const char*
name, STRLEN len, I32 level);
/* PERL_CALLCONV GV* Perl_gv_fetchmethod(pTHX_ HV* stash, const char* name);
*/
@@ -1086,6 +1089,10 @@
__attribute__malloc__
__attribute__warn_unused_result__;
+PERL_CALLCONV char* Perl_savesharedpvn(pTHX_ const char *const pv, const
STRLEN len)
+ __attribute__malloc__
+ __attribute__warn_unused_result__;
+
PERL_CALLCONV void Perl_savestack_grow(pTHX);
PERL_CALLCONV void Perl_savestack_grow_cnt(pTHX_ I32 need);
PERL_CALLCONV void Perl_save_aelem(pTHX_ AV* av, I32 idx, SV **sptr);
@@ -1966,7 +1973,7 @@
STATIC void S_checkcomma(pTHX_ const char *s, const char *name, const char
*what);
STATIC void S_force_ident(pTHX_ const char *s, int kind);
-STATIC void S_incline(pTHX_ char *s);
+STATIC void S_incline(pTHX_ const char *s);
STATIC int S_intuit_method(pTHX_ char *s, GV *gv, CV *cv);
STATIC int S_intuit_more(pTHX_ char *s);
STATIC I32 S_lop(pTHX_ I32 f, int x, char *s);
==== //depot/maint-5.8/perl/sv.c#343 (text) ====
Index: perl/sv.c
--- perl/sv.c#342~30291~ 2007-02-14 08:37:49.000000000 -0800
+++ perl/sv.c 2007-02-14 09:29:10.000000000 -0800
@@ -402,9 +402,9 @@
static void
do_clean_objs(pTHX_ SV *sv)
{
- SV* rv;
+ SV *const rv = SvRV(sv);
- if (SvROK(sv) && SvOBJECT(rv = SvRV(sv))) {
+ if (SvOBJECT(rv)) {
DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "),
sv_dump(sv)));
if (SvWEAKREF(sv)) {
sv_del_backref(sv);
@@ -426,7 +426,7 @@
static void
do_clean_named_objs(pTHX_ SV *sv)
{
- if (SvTYPE(sv) == SVt_PVGV && GvGP(sv)) {
+ if (GvGP(sv)) {
if ((
#ifdef PERL_DONT_CREATE_GVSV
GvSV(sv) &&
==== //depot/maint-5.8/perl/t/comp/parser.t#18 (text) ====
Index: perl/t/comp/parser.t
--- perl/t/comp/parser.t#17~29996~ 2007-01-26 01:54:13.000000000 -0800
+++ perl/t/comp/parser.t 2007-02-14 09:29:10.000000000 -0800
@@ -9,7 +9,7 @@
}
require "./test.pl";
-plan( tests => 56 );
+plan( tests => 92 );
eval '[EMAIL PROTECTED];';
like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '[EMAIL
PROTECTED]' );
@@ -194,3 +194,81 @@
eval q{ s/x/#/e };
is( $@, '', 'comments in s///e' );
+
+# Add new tests HERE:
+
+# More awkward tests for #line. Keep these at the end, as they will screw
+# with sane line reporting for any other test failures
+
+sub check ($$$) {
+ my ($file, $line, $name) = @_;
+ my (undef, $got_file, $got_line) = caller;
+ like ($got_file, $file, "file of $name");
+ is ($got_line, $line, "line of $name");
+}
+
+#line 3
+check(qr/parser\.t$/, 3, "bare line");
+
+# line 5
+check(qr/parser\.t$/, 5, "bare line with leading space");
+
+#line 7
+check(qr/parser\.t$/, 7, "trailing space still valid");
+
+# line 11
+check(qr/parser\.t$/, 11, "leading and trailing");
+
+# line 13
+check(qr/parser\.t$/, 13, "leading tab");
+
+#line 17
+check(qr/parser\.t$/, 17, "middle tab");
+
+#line 19
+check(qr/parser\.t$/, 19, "loadsaspaces");
+
+#line 23 KASHPRITZA
+check(qr/^KASHPRITZA$/, 23, "bare filename");
+
+#line 29 "KAHEEEE"
+check(qr/^KAHEEEE$/, 29, "filename in quotes");
+
+#line 31 "CLINK CLOINK BZZT"
+check(qr/^CLINK CLOINK BZZT$/, 31, "filename with spaces in quotes");
+
+#line 37 "THOOM THOOM"
+check(qr/^THOOM THOOM$/, 37, "filename with tabs in quotes");
+
+#line 41 "GLINK PLINK GLUNK DINK"
+check(qr/^GLINK PLINK GLUNK DINK$/, 41, "a space after the quotes");
+
+#line 43 "BBFRPRAFPGHPP
+check(qr/^"BBFRPRAFPGHPP$/, 43, "actually missing a quote is still valid");
+
+#line 47 bang eth
+check(qr/^"BBFRPRAFPGHPP$/, 46, "but spaces aren't allowed without quotes");
+
+eval <<'EOSTANZA'; die $@ if $@;
+#line 51 "With wonderful deathless ditties|We build up the world's great
cities,|And out of a fabulous story|We fashion an empire's glory:|One man with
a dream, at pleasure,|Shall go forth and conquer a crown;|And three with a new
song's measure|Can trample a kingdom down."
+check(qr/^With.*down\.$/, 51, "Overflow the second small buffer check");
+EOSTANZA
+
+# And now, turn on the debugger flag for long names
+$^P = 0x100;
+
+#line 53 "For we are afar with the dawning|And the suns that are not yet
high,|And out of the infinite morning|Intrepid you hear us cry-|How, spite of
your human scorning,|Once more God's future draws nigh,|And already goes forth
the warning|That ye of the past must die."
+check(qr/^For we.*must die\.$/, 53, "Our long line is set up");
+
+eval <<'EOT'; die $@ if $@;
+#line 59 " "
+check(qr/^ $/, 59, "Overflow the first small buffer check only");
+EOT
+
+eval <<'EOSTANZA'; die $@ if $@;
+#line 61 "Great hail! we cry to the comers|From the dazzling unknown
shore;|Bring us hither your sun and your summers;|And renew our world as of
yore;|You shall teach us your song's new numbers,|And things that we dreamed
not before:|Yea, in spite of a dreamer who slumbers,|And a singer who sings no
more."
+check(qr/^Great hail!.*no more\.$/, 61, "Overflow both small buffer checks");
+EOSTANZA
+
+__END__
+# Don't add new tests HERE. See note above
==== //depot/maint-5.8/perl/toke.c#166 (text) ====
Index: perl/toke.c
--- perl/toke.c#165~30291~ 2007-02-14 08:37:49.000000000 -0800
+++ perl/toke.c 2007-02-14 09:29:10.000000000 -0800
@@ -653,12 +653,11 @@
*/
STATIC void
-S_incline(pTHX_ char *s)
+S_incline(pTHX_ const char *s)
{
- char *t;
- char *n;
- char *e;
- char ch;
+ const char *t;
+ const char *n;
+ const char *e;
CopLINE_inc(PL_curcop);
if (*s++ != '#')
@@ -698,34 +697,48 @@
if (*e != '\n' && *e != '\0')
return; /* false alarm */
- ch = *t;
- *t = '\0';
if (t - s > 0) {
+ const STRLEN len = t - s;
#ifndef USE_ITHREADS
const char * const cf = CopFILE(PL_curcop);
STRLEN tmplen = cf ? strlen(cf) : 0;
if (tmplen > 7 && strnEQ(cf, "(eval ", 6)) {
/* must copy *{"::_<(eval N)[oldfilename:L]"}
* to *{"::_<newfilename"} */
- char smallbuf[256], smallbuf2[256];
- char *tmpbuf, *tmpbuf2;
- GV **gvp, *gv2;
- STRLEN tmplen2 = strlen(s);
- if (tmplen + 3 < sizeof smallbuf)
+ /* However, the long form of evals is only turned on by the
+ debugger - usually they're "(eval %lu)" */
+ char smallbuf[128];
+ char *tmpbuf;
+ GV **gvp;
+ STRLEN tmplen2 = len;
+ if (tmplen + 2 <= sizeof smallbuf)
tmpbuf = smallbuf;
else
- Newx(tmpbuf, tmplen + 3, char);
- if (tmplen2 + 3 < sizeof smallbuf2)
- tmpbuf2 = smallbuf2;
- else
- Newx(tmpbuf2, tmplen2 + 3, char);
- tmpbuf[0] = tmpbuf2[0] = '_';
- tmpbuf[1] = tmpbuf2[1] = '<';
- memcpy(tmpbuf + 2, cf, ++tmplen);
- memcpy(tmpbuf2 + 2, s, ++tmplen2);
- ++tmplen; ++tmplen2;
+ Newx(tmpbuf, tmplen + 2, char);
+ tmpbuf[0] = '_';
+ tmpbuf[1] = '<';
+ memcpy(tmpbuf + 2, cf, tmplen);
+ tmplen += 2;
gvp = (GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, FALSE);
if (gvp) {
+ char *tmpbuf2;
+ GV *gv2;
+
+ if (tmplen2 + 2 <= sizeof smallbuf)
+ tmpbuf2 = smallbuf;
+ else
+ Newx(tmpbuf2, tmplen2 + 2, char);
+
+ if (tmpbuf2 != smallbuf || tmpbuf != smallbuf) {
+ /* Either they malloc'd it, or we malloc'd it,
+ so no prefix is present in ours. */
+ tmpbuf2[0] = '_';
+ tmpbuf2[1] = '<';
+ }
+
+ memcpy(tmpbuf2 + 2, s, tmplen2);
+ tmplen2 += 2;
+
gv2 = *(GV**)hv_fetch(PL_defstash, tmpbuf2, tmplen2, TRUE);
if (!isGV(gv2)) {
gv_init(gv2, PL_defstash, tmpbuf2, tmplen2, FALSE);
@@ -734,15 +747,15 @@
GvHV(gv2) = (HV*)SvREFCNT_inc(GvHV(*gvp));
GvAV(gv2) = (AV*)SvREFCNT_inc(GvAV(*gvp));
}
+
+ if (tmpbuf2 != smallbuf) Safefree(tmpbuf2);
}
if (tmpbuf != smallbuf) Safefree(tmpbuf);
- if (tmpbuf2 != smallbuf2) Safefree(tmpbuf2);
}
#endif
CopFILE_free(PL_curcop);
- CopFILE_set(PL_curcop, s);
+ CopFILE_setn(PL_curcop, s, len);
}
- *t = ch;
CopLINE_set(PL_curcop, atoi(n)-1);
}
@@ -814,7 +827,7 @@
{
/* end of file. Add on the -p or -n magic */
if (PL_minus_p) {
- sv_setpv(PL_linestr,
+ sv_setpvs(PL_linestr,
";}continue{print or die qq(-p destination: $!\\n);}");
PL_minus_n = PL_minus_p = 0;
}
@@ -5504,8 +5517,8 @@
/* remember buffer pos'n for later force_word */
tboffset = s - PL_oldbufptr;
d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
- if (strchr(tmpbuf, ':'))
- sv_setpv(PL_subname, tmpbuf);
+ if (memchr(tmpbuf, ':', len))
+ sv_setpvn(PL_subname, tmpbuf, len);
else {
sv_setsv(PL_subname,PL_curstname);
sv_catpvs(PL_subname,"::");
==== //depot/maint-5.8/perl/util.c#146 (text) ====
Index: perl/util.c
--- perl/util.c#145~30226~ 2007-02-12 06:48:32.000000000 -0800
+++ perl/util.c 2007-02-14 09:29:10.000000000 -0800
@@ -941,6 +941,27 @@
}
/*
+=for apidoc savesharedpvn
+
+A version of C<savepvn()> which allocates the duplicate string in memory
+which is shared between threads. (With the specific difference that a NULL
+pointer is not acceptable)
+
+=cut
+*/
+char *
+Perl_savesharedpvn(pTHX_ const char *const pv, const STRLEN len)
+{
+ char *const newaddr = (char*)PerlMemShared_malloc(len + 1);
+ assert(pv);
+ if (!newaddr) {
+ return write_no_mem();
+ }
+ newaddr[len] = '\0';
+ return (char*)memcpy(newaddr, pv, len);
+}
+
+/*
=for apidoc savesvpv
A version of C<savepv()>/C<savepvn()> which gets the string to duplicate from
End of Patch.