Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simple optimiser bug in perl-5.005_63, sample included #988

Closed
p5pRT opened this issue Dec 23, 1999 · 5 comments
Closed

simple optimiser bug in perl-5.005_63, sample included #988

p5pRT opened this issue Dec 23, 1999 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 23, 1999

Migrated from rt.perl.org#1937 (status was 'resolved')

Searchable as RT1937$

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 1999

From cameron@research.canon.com.au

The following code prints "H H ". It should print "H 1234-5678".

  #!/usr/bin/perl
  my $home='1234-5678';
  $home="H ".(ref $home ? "@​$home" : $home);
  print "$home\n";

It behaves correctly if $home is not a "my" variable.

Perl Info


This perlbug was built using Perl 5.00464 - Mon Oct 19 16:54:06 EST 1998
It is being executed now by  Perl 5.00563 - Tue Dec 21 15:11:08 EST 1999.

Site configuration information for perl 5.00563:

Configured by cameron at Tue Dec 21 15:11:08 EST 1999.

Summary of my perl5 (revision 5.0 version 5 subversion 63) configuration:
  Platform:
    osname=solaris, osvers=2.5.1, archname=sun4-solaris
    uname='sunos elph.research.canon.com.au 5.5.1 generic_103640-29 sun4u sparc sunw,ultra-enterprise '
    config_args='-Duse64bits'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=define d_sfio=undef
    use64bits=define usemultiplicity=undef
  Compiler:
    cc='gcc', optimize='-O', gccversion=2.8.1
    cppflags='-I/usr/local/include'
    ccflags ='-I/usr/local/include -DUSE_LONG_LONG'
    stdchar='unsigned char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib'
    libpth=/lib /usr/lib /usr/local/lib
    libs=-lsfio -lsocket -lnsl -lgdbm -ldb -ldl -lm -lc -lcrypt -lsec
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib'

Locally applied patches:
	


@INC for perl 5.00563:
	/home/sid/cameron/rc/perl
	/opt/perl-5.005_63/lib/5.00563/sun4-solaris
	/opt/perl-5.005_63/lib/5.00563
	/opt/perl-5.005_63/lib/site_perl/5.00563/sun4-solaris
	/opt/perl-5.005_63/lib/site_perl
	.


Environment for perl 5.00563:
    HOME=/home/sid/cameron
    LANG=C
    LD_LIBRARY_PATH=/home/sid/cameron/lib/sun.sparc.solaris:/usr/lib:/home/sid/cameron/lib/sun.sparc.solaris/5.5.1:/usr/local/lib:/usr/ccs/lib:/usr/local/lib/jdk/lib:/usr/X11R6.4/lib:/usr/X11R6.3/lib:/usr/local/X11/lib:/usr/local/X11R6.3/lib:/usr/dt/lib:/usr/openwin/lib:/opt/gnu/lib:/opt/RICHPse/lib:/opt/SUNWdxlib/lib:/opt/apple/lib:/opt/flexlm/lib:/opt/ncs/lib:/opt/perl-5.004pl64/lib:/opt/perl/lib:/opt/Eterm/lib:/opt/egcs-1.1.2-sol2.5.1/lib:/opt/egcs-1.1.2-sol2.6/lib:/opt/mysql/lib:/opt/jdk/lib:/opt/netscape-4.6/lib:/opt/SSLeay/lib:/opt/imlib-1.9.4/lib:/opt/netscape-4.51/lib:/opt/ldap/lib:/opt/xemacs/lib:/opt/ispell/lib:/opt/gnome/lib:/opt/mutt/lib:/opt/unixodbc-1.6/lib:/opt/openssl/lib:/opt/BKgnome/lib:/opt/StarOffice/lib:/usr/ucblib:/usr/local/lib/pgp5/lib:/usr/local/lib/postgres/lib
    LOGDIR (unset)
    PATH=/home/sid/cameron/stubs:/home/sid/cameron/bin/sun.sparc.solaris/5.5.1:/home/sid/cameron/bin/sun.sparc.solaris:/home/sid/cameron/scripts:/home/sid/cameron/scripts/hosts:/usr/openwin/bin:/bin:/usr/ucb:/usr/local/bin:/usr/local/script:/usr/X11R6/bin:/usr/local/X11/bin:/usr/sbin:/sbin:/usr/sadm/bin:/etc:/usr/local/etc:/usr/ccs/bin:/usr/X11R6.3/bin:/usr/local/X11R6.3/bin:/usr/dt/bin:/usr/local/lib/fvwm2/bin:/usr/local/lib/ImageMagick/bin:/home/elph/ddts/bin_SunOS_5:/opt/gnu/bin:/usr/games:/opt/RICHPse/bin:/opt/SUNWdxlib/bin:/opt/SUNWrtvc/bin:/opt/apple/bin:/opt/fvwm-2.2/bin:/opt/acrobat/bin:/opt/flexlm/bin:/opt/netls/bin:/opt/ncs/bin:/opt/acrobat-3.02/bin:/opt/apache/bin:/opt/fvwm/bin:/opt/perl-5.004pl64/bin:/opt/perl/bin:/opt/xanim-2.80.1/bin:/opt/Eterm/bin:/opt/egcs-1.1.2-sol2.5.1/bin:/opt/egcs-1.1.2-sol2.6/bin:/opt/mysql/bin:/opt/jdk/bin:/opt/xscreensaver/bin:/opt/SSLeay/bin:/opt/imlib-1.9.4/bin:/opt/ldap/bin:/opt/nntpcache/bin:/opt/xpdf/bin:/opt/netpbm/bin:/opt/xemacs/!
bin:/opt/ispell/bin:/opt/afterstep/bin:/opt/gnome/bin:/opt/mutt/bin:/opt/unixodbc-1.6/bin:/opt/smb2www/bin:/opt/apache-1.3.9/bin:/opt/openssl/bin:/opt/BKgnome/bin:/opt/StarOffice/bin:/opt/nntpcache/sbin:/usr/local/lib/pgp5/bin:/usr/local/lib/postgres/bin
    PERL5LIB=/home/sid/cameron/rc/perl
    PERLLIB=/home/sid/cameron/rc/perl:/usr/local/lib/perl4:/usr/local/lib/perl
    PERL_BADLANG (unset)
    SHELL=/bin/ae

@p5pRT
Copy link
Author

p5pRT commented Dec 24, 1999

From [Unknown Contact. See original ticket]

Cameron Simpson writes​:

The following code prints "H H ". It should print "H 1234-5678".

\#\!/usr/bin/perl
my $home='1234\-5678';
$home="H "\.\(ref $home ? "@​$home" : $home\);
print "$home\\n";

It behaves correctly if $home is not a "my" variable.

Uh-oh! OP_CONCAT with lex_assign optimization. I thought this was
fixed already... Will look again.

Ilya

@p5pRT
Copy link
Author

p5pRT commented Dec 24, 1999

From [Unknown Contact. See original ticket]

Cameron Simpson writes​:

The following code prints "H H ". It should print "H 1234-5678".

\#\!/usr/bin/perl
my $home='1234\-5678';
$home="H "\.\(ref $home ? "@​$home" : $home\);
print "$home\\n";

This shows that compile-time checks for "dangerous ops" (those which
behave "wrong" if target coincides with one of the args) are not enough.

Here OP_CONCAT has a target which may coincide with the right
argument, but it is pretty hopeless to detect this at compile time
(one needs a list of OPs which may return a random lexical variable).

The fix for CONCAT happens to be simple​: a check at run-time may
actually *speed* things up. What remains is to decide what to do with
two other "dangerous" ops​: OP_JOIN and OP_QUOTEMETA. My guts say that
optimization of OP_JOIN is pretty important, and it would be a pity to
lose it...

Ilya

P.S. Can somebody with good memory of OOK-hack vgrep the last chunk
  wrt possible optimizations?

Inline Patch
--- ./pp_hot.c-pre	Fri Dec 24 17:08:09 1999
+++ ./pp_hot.c	Fri Dec 24 17:59:24 1999
@@ -153,9 +153,17 @@ PP(pp_concat)
     dPOPTOPssrl;
     STRLEN len;
     char *s;
+
     if (TARG != left) {
-	s = SvPV(left,len);
-	sv_setpvn(TARG,s,len);
+	STRLEN l;
+	char *s1 = SvPV(left,l);
+
+	if (TARG == right) {		/* Should be rare, most cases
+					   eliminated by ck_concat */
+	    sv_precatpvn(TARG, s1, l);
+	    goto done;
+	}
+	sv_setpvn(TARG,s1,l);
     }
     else if (SvGMAGICAL(TARG))
 	mg_get(TARG);
@@ -181,6 +189,7 @@ PP(pp_concat)
     }
     else
 	sv_setpvn(TARG,s,len);	/* suppress warning */
+  done:
     SETTARG;
     RETURN;
   }
--- ./t/op/lex_assign.t~	Sun Oct 24 07:51:32 1999
+++ ./t/op/lex_assign.t	Fri Dec 24 16:42:35 1999
@@ -24,7 +24,7 @@ sub subb {"in s"}
 
 @INPUT = <DATA>;
 @simple_input = grep /^\s*\w+\s*\$\w+\s*[#\n]/, @INPUT;
-print "1..", (8 + @INPUT + @simple_input), "\n";
+print "1..", (9 + @INPUT + @simple_input), "\n";
 $ord = 0;
 
 sub wrn {"@_"}
@@ -51,6 +51,12 @@ $b = $a+5;
 
 $ord++;
 print "not " unless $dc == 1;
+print "ok $ord\n";
+
+$ord++;
+my $xxx = 'b';
+$xxx = 'c' . ($xxx || 'e');
+print "not " unless $xxx eq 'cb';
 print "ok $ord\n";
 
 {				# Check calling STORE
--- ./op.c~	Thu Dec  9 04:17:01 1999
+++ ./op.c	Fri Dec 24 17:44:49 1999
@@ -5593,13 +5593,7 @@ Perl_ck_sassign(pTHX_ OP *o)
 	if (kkid && kkid->op_type == OP_PADSV
 	    && !(kkid->op_private & OPpLVAL_INTRO))
 	{
-	    /* Concat has problems if target is equal to right arg. */
-	    if (kid->op_type == OP_CONCAT) {
-		if (kLISTOP->op_first->op_sibling->op_type == OP_PADSV
-		    && kLISTOP->op_first->op_sibling->op_targ == kkid->op_targ)
-		    return o;
-	    }
-	    else if (kid->op_type == OP_JOIN) {
+	    if (kid->op_type == OP_JOIN) {
 		/* do_join has problems if the arguments coincide with target.
 		   In fact the second argument *can* safely coincide,
 		   but ignore=pessimize this rare occasion. */
--- ./embed.pl~	Thu Dec  9 02:40:50 1999
+++ ./embed.pl	Fri Dec 24 17:59:09 1999
@@ -1698,6 +1698,7 @@ p	|char*	|sv_peek	|SV* sv
 p	|void	|sv_pos_u2b	|SV* sv|I32* offsetp|I32* lenp
 p	|void	|sv_pos_b2u	|SV* sv|I32* offsetp
 p	|char*	|sv_pvn_force	|SV* sv|STRLEN* lp
+p	|void	|sv_precatpvn	|SV* sv|const char* ptr|STRLEN len
 p	|char*	|sv_reftype	|SV* sv|int ob
 p	|void	|sv_replace	|SV* sv|SV* nsv
 p	|void	|sv_report_used
--- ./sv.c~	Thu Dec  9 04:07:22 1999
+++ ./sv.c	Fri Dec 24 17:55:12 1999
@@ -2850,6 +2850,24 @@ Perl_sv_catpvn(pTHX_ register SV *sv, re
 }
 
 void
+Perl_sv_precatpvn(pTHX_ register SV *sv, register const char *ptr, register STRLEN len)
+{
+    STRLEN tlen;
+    char *junk;
+
+    junk = SvPV_force(sv, tlen);
+    SvGROW(sv, tlen + len + 1);
+    if (ptr == junk)
+	ptr = SvPVX(sv);
+    Move(SvPVX(sv),SvPVX(sv)+len,tlen,char);
+    Move(ptr,SvPVX(sv),len,char);
+    SvCUR(sv) += len;
+    *SvEND(sv) = '\0';
+    (void)SvPOK_only(sv);		/* validate pointer */
+    SvTAINT(sv);
+}
+
+void
 Perl_sv_catpvn_mg(pTHX_ register SV *sv, register const char *ptr, register STRLEN len)
 {
     sv_catpvn(sv,ptr,len);

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2000

From @gsar

On Fri, 24 Dec 1999 18​:20​:59 EST, Ilya Zakharevich wrote​:

Cameron Simpson writes​:

The following code prints "H H ". It should print "H 1234-5678".

\#\!/usr/bin/perl
my $home='1234\-5678';
$home="H "\.\(ref $home ? "@&#8203;$home" : $home\);
print "$home\\n";

This shows that compile-time checks for "dangerous ops" (those which
behave "wrong" if target coincides with one of the args) are not enough.

Here OP_CONCAT has a target which may coincide with the right
argument, but it is pretty hopeless to detect this at compile time
(one needs a list of OPs which may return a random lexical variable).

The fix for CONCAT happens to be simple​: a check at run-time may
actually *speed* things up. What remains is to decide what to do with
two other "dangerous" ops​: OP_JOIN and OP_QUOTEMETA. My guts say that

I've decided to disable the optimization for those two. Let me know
if/when someone figures out a _correct_ way to do it.

optimization of OP_JOIN is pretty important, and it would be a pity to
lose it...

Ilya

P.S. Can somebody with good memory of OOK-hack vgrep the last chunk
wrt possible optimizations?
[...]
+ sv_precatpvn(TARG, s1, l);
+ goto done;
[...]
void
+Perl_sv_precatpvn(pTHX_ register SV *sv, register const char *ptr, register STRLEN len)
+{
+ STRLEN tlen;
+ char *junk;
+
+ junk = SvPV_force(sv, tlen);
+ SvGROW(sv, tlen + len + 1);
+ if (ptr == junk)
+ ptr = SvPVX(sv);
+ Move(SvPVX(sv),SvPVX(sv)+len,tlen,char);
+ Move(ptr,SvPVX(sv),len,char);
+ SvCUR(sv) += len;
+ *SvEND(sv) = '\0';
+ (void)SvPOK_only(sv); /* validate pointer */
+ SvTAINT(sv);
+}

sv_insert() was meant to do what you're doing above, so why not use
that?

Sarathy
gsar@​ActiveState.com

Inline Patch
-----------------------------------8<-----------------------------------
Change 4749 by gsar@auger on 2000/01/02 21:37:29

	disable optimization in change#3612 for join() and quotemeta()--this
	removes all the gross hacks for the special cases in that change; fix
	pp_concat() for when TARG == arg (modified version of patch suggested
	by Ilya Zakharevich)

Affected files ...

... //depot/perl/op.c#230 edit
... //depot/perl/opcode.h#57 edit
... //depot/perl/opcode.pl#61 edit
... //depot/perl/pp_hot.c#152 edit
... //depot/perl/sv.c#183 edit
... //depot/perl/t/op/lex_assign.t#11 edit

Differences ...

==== //depot/perl/op.c#230 (text) ====
Index: perl/op.c
--- perl/op.c.~1~	Sun Jan  2 13:37:33 2000
+++ perl/op.c	Sun Jan  2 13:37:33 2000
@@ -5593,31 +5593,6 @@
 	if (kkid && kkid->op_type == OP_PADSV
 	    && !(kkid->op_private & OPpLVAL_INTRO))
 	{
-	    /* Concat has problems if target is equal to right arg. */
-	    if (kid->op_type == OP_CONCAT) {
-		if (kLISTOP->op_first->op_sibling->op_type == OP_PADSV
-		    && kLISTOP->op_first->op_sibling->op_targ == kkid->op_targ)
-		    return o;
-	    }
-	    else if (kid->op_type == OP_JOIN) {
-		/* do_join has problems if the arguments coincide with target.
-		   In fact the second argument *can* safely coincide,
-		   but ignore=pessimize this rare occasion. */
-		OP *arg = kLISTOP->op_first->op_sibling; /* Skip PUSHMARK */
-
-		while (arg) {
-		    if (arg->op_type == OP_PADSV
-			&& arg->op_targ == kkid->op_targ)
-			return o;
-		    arg = arg->op_sibling;
-		}
-	    }
-	    else if (kid->op_type == OP_QUOTEMETA) {
-		/* quotemeta has problems if the argument coincides with target. */
-		if (kLISTOP->op_first->op_type == OP_PADSV
-		    && kLISTOP->op_first->op_targ == kkid->op_targ)
-		    return o;
-	    }
 	    kid->op_targ = kkid->op_targ;
 	    kkid->op_targ = 0;
 	    /* Now we do not need PADSV and SASSIGN. */
@@ -6201,26 +6176,13 @@
 	case OP_UCFIRST:
 	case OP_LC:
 	case OP_LCFIRST:
-	    if ( o->op_next && o->op_next->op_type == OP_STRINGIFY
-		 && !(o->op_next->op_private & OPpTARGET_MY) )
-		null(o->op_next);
-	    o->op_seq = PL_op_seqmax++;
-	    break;
 	case OP_CONCAT:
 	case OP_JOIN:
 	case OP_QUOTEMETA:
 	    if (o->op_next && o->op_next->op_type == OP_STRINGIFY) {
 		if (o->op_next->op_private & OPpTARGET_MY) {
-		    if ((o->op_flags & OPf_STACKED) /* chained concats */
-			|| (o->op_type == OP_CONCAT
-	    /* Concat has problems if target is equal to right arg. */
-			    && (((LISTOP*)o)->op_first->op_sibling->op_type
-				== OP_PADSV)
-			    && (((LISTOP*)o)->op_first->op_sibling->op_targ
-				== o->op_next->op_targ)))
-		    {
+		    if (o->op_flags & OPf_STACKED) /* chained concats */
 			goto ignore_optimization;
-		    }
 		    else {
 			o->op_targ = o->op_next->op_targ;
 			o->op_next->op_targ = 0;

==== //depot/perl/opcode.h#57 (text+w) ====
Index: perl/opcode.h
--- perl/opcode.h.~1~	Sun Jan  2 13:37:33 2000
+++ perl/opcode.h	Sun Jan  2 13:37:33 2000
@@ -1576,7 +1576,7 @@
 	0x0001368e,	/* lcfirst */
 	0x0001368e,	/* uc */
 	0x0001368e,	/* lc */
-	0x0001378e,	/* quotemeta */
+	0x0001368e,	/* quotemeta */
 	0x00000248,	/* rv2av */
 	0x00026c04,	/* aelemfast */
 	0x00026404,	/* aelem */
@@ -1592,7 +1592,7 @@
 	0x00022800,	/* unpack */
 	0x0004280d,	/* pack */
 	0x00222808,	/* split */
-	0x0004290d,	/* join */
+	0x0004280d,	/* join */
 	0x00004801,	/* list */
 	0x00448400,	/* lslice */
 	0x00004805,	/* anonlist */

==== //depot/perl/opcode.pl#61 (xtext) ====
Index: perl/opcode.pl
--- perl/opcode.pl.~1~	Sun Jan  2 13:37:33 2000
+++ perl/opcode.pl	Sun Jan  2 13:37:33 2000
@@ -298,6 +298,7 @@
 #	ref not OK (RETPUSHNO)
 #	trans not OK (dTARG; TARG = sv_newmortal();)
 #	ucfirst etc not OK: TMP arg processed inplace
+#	quotemeta not OK (unsafe when TARG == arg)
 #	each repeat not OK too due to array context
 #	pack split - unknown whether they are safe
 #	sprintf: is calling do_sprintf(TARG,...) which can act on TARG
@@ -314,6 +315,7 @@
 #	readline - unknown whether it is safe
 #	match subst not OK (dTARG)
 #	grepwhile not OK (not always setting)
+#	join not OK (unsafe when TARG == arg)
 
 #	Suspicious wrt "additional mode of failure": concat (dealt with
 #	in ck_sassign()), join (same).
@@ -506,7 +508,7 @@
 lcfirst		lcfirst			ck_fun_locale	fstu%	S?
 uc		uc			ck_fun_locale	fstu%	S?
 lc		lc			ck_fun_locale	fstu%	S?
-quotemeta	quotemeta		ck_fun		fsTu%	S?
+quotemeta	quotemeta		ck_fun		fstu%	S?
 
 # Arrays.
 
@@ -531,7 +533,7 @@
 unpack		unpack			ck_fun		@	S S
 pack		pack			ck_fun		mst@	S L
 split		split			ck_split	t@	S S S
-join		join			ck_join		msT@	S L
+join		join			ck_join		mst@	S L
 
 # List operators.
 

==== //depot/perl/pp_hot.c#152 (text) ====
Index: perl/pp_hot.c
--- perl/pp_hot.c.~1~	Sun Jan  2 13:37:33 2000
+++ perl/pp_hot.c	Sun Jan  2 13:37:33 2000
@@ -152,8 +152,14 @@
     dPOPTOPssrl;
     STRLEN len;
     char *s;
+
     if (TARG != left) {
 	s = SvPV(left,len);
+	if (TARG == right) {
+	    sv_insert(TARG, 0, 0, s, len);
+	    SETs(TARG);
+	    RETURN;
+	}
 	sv_setpvn(TARG,s,len);
     }
     else if (SvGMAGICAL(TARG))

==== //depot/perl/sv.c#183 (text) ====
Index: perl/sv.c
--- perl/sv.c.~1~	Sun Jan  2 13:37:33 2000
+++ perl/sv.c	Sun Jan  2 13:37:33 2000
@@ -3210,6 +3210,7 @@
 	SvCUR_set(bigstr, offset+len);
     }
 
+    SvTAINT(bigstr);
     i = littlelen - len;
     if (i > 0) {			/* string might grow */
 	big = SvGROW(bigstr, SvCUR(bigstr) + i + 1);

==== //depot/perl/t/op/lex_assign.t#11 (xtext) ====
Index: perl/t/op/lex_assign.t
--- perl/t/op/lex_assign.t.~1~	Sun Jan  2 13:37:33 2000
+++ perl/t/op/lex_assign.t	Sun Jan  2 13:37:33 2000
@@ -24,7 +24,7 @@
 
 @INPUT = <DATA>;
 @simple_input = grep /^\s*\w+\s*\$\w+\s*[#\n]/, @INPUT;
-print "1..", (8 + @INPUT + @simple_input), "\n";
+print "1..", (9 + @INPUT + @simple_input), "\n";
 $ord = 0;
 
 sub wrn {"@_"}
@@ -53,6 +53,12 @@
 print "not " unless $dc == 1;
 print "ok $ord\n";
 
+$ord++;
+my $xxx = 'b';
+$xxx = 'c' . ($xxx || 'e');
+print "not " unless $xxx eq 'cb';
+print "ok $ord\n";
+
 {				# Check calling STORE
   my $sc = 0;
   sub B::TIESCALAR {bless [11], 'B'}
End of Patch.

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2000

From [Unknown Contact. See original ticket]

On Wed, Jan 05, 2000 at 10​:58​:17AM -0800, Gurusamy Sarathy wrote​:

The fix for CONCAT happens to be simple​: a check at run-time may
actually *speed* things up. What remains is to decide what to do with
two other "dangerous" ops​: OP_JOIN and OP_QUOTEMETA. My guts say that

I've decided to disable the optimization for those two. Let me know
if/when someone figures out a _correct_ way to do it.

I will.

void
+Perl_sv_precatpvn(pTHX_ register SV *sv, register const char *ptr, register STRLEN len)
+{
+ STRLEN tlen;
+ char *junk;
+
+ junk = SvPV_force(sv, tlen);
+ SvGROW(sv, tlen + len + 1);
+ if (ptr == junk)
+ ptr = SvPVX(sv);
+ Move(SvPVX(sv),SvPVX(sv)+len,tlen,char);
+ Move(ptr,SvPVX(sv),len,char);
+ SvCUR(sv) += len;
+ *SvEND(sv) = '\0';
+ (void)SvPOK_only(sv); /* validate pointer */
+ SvTAINT(sv);
+}

sv_insert() was meant to do what you're doing above, so why not use
that?

Ignorance. Additionally, this gives a shorter path through the forest
of conditional in sv_insert, so it has an added value too.

Ilya

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant