diff options
-rw-r--r-- | pod/perlguts.pod | 7 | ||||
-rw-r--r-- | sv.c | 6 |
2 files changed, 10 insertions, 3 deletions
diff --git a/pod/perlguts.pod b/pod/perlguts.pod index 422549e616..fa05c23560 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -261,9 +261,10 @@ somewhere inside the PV, and it discards everything before the pointer. The efficiency comes by means of a little hack: instead of actually removing the characters, C<sv_chop> sets the flag C<OOK> (offset OK) to signal to other functions that the offset hack is in -effect, and it puts the number of bytes chopped off into the IV field -of the SV. It then moves the PV pointer (called C<SvPVX>) forward that -many bytes, and adjusts C<SvCUR> and C<SvLEN>. +effect, and it moves the PV pointer (called C<SvPVX>) forward +by the number of bytes chopped off, and adjusts C<SvCUR> and C<SvLEN> +accordingly. (A portion of the space between the old and new PV +pointers is used to store the count of chopped bytes.) Hence, at this point, the start of the buffer that we allocated lives at C<SvPVX(sv) - SvIV(sv)> in memory and the PV pointer is pointing @@ -5075,8 +5075,14 @@ Perl_sv_chop(pTHX_ SV *const sv, const char *const ptr) evacp = p - evacn; #endif + /* This sets 'delta' to the accumulated value of all deltas so far */ delta += old_delta; assert(delta); + + /* If 'delta' fits in a byte, store it just prior to the new beginning of + * the string; otherwise store a 0 byte there and store 'delta' just prior + * to that, using as many bytes as a STRLEN occupies. Thus it overwrites a + * portion of the chopped part of the string */ if (delta < 0x100) { *--p = (U8) delta; } else { |