summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2008-01-04 23:12:01 +0000
committerDavid Mitchell <davem@iabyn.com>2009-03-19 11:52:02 +0000
commit0dd1a9749ac502e8f2a908316f20bb86c496ba03 (patch)
tree769a3697bb2ff40d7af2a85222d6b8486cc7b641 /sv.c
parent7e20f6b640c6e7cd33348abf039f3f85e1e8b474 (diff)
downloadperl-0dd1a9749ac502e8f2a908316f20bb86c496ba03.tar.gz
revert the SvOOK re-implementation:
------------ Re-implement the SvOOK() hack to store the offset as a BER encoded number in the part of the PVX that is being released. (It will always fit, as chopping off 1 byte gives just enough space for recording a delta of up to 127). This allows SvOOK() to co-exist with SvIOK_on(), which means all the calls to SvOOK_off() [with the possibility of a call to sv_backoff()] in SvIOK_on() can be removed. This ought to make a lot of straight line code a little bit simpler. OOK()d scalars can now be SVt_PV, as the IVX isn't needed. p4raw-id: //depot/perl@32836 (cherry-picked from commit 7a4bba223aa750dd886fe6a2fddef224e59c717f) ------------
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c123
1 files changed, 38 insertions, 85 deletions
diff --git a/sv.c b/sv.c
index aacc713dbc..8c6414312c 100644
--- a/sv.c
+++ b/sv.c
@@ -1441,16 +1441,27 @@ wrapper instead.
int
Perl_sv_backoff(pTHX_ register SV *sv)
{
- UV delta = sv_read_offset(sv);
- const char * const s = SvPVX_const(sv);
PERL_UNUSED_CONTEXT;
assert(SvOOK(sv));
assert(SvTYPE(sv) != SVt_PVHV);
assert(SvTYPE(sv) != SVt_PVAV);
-
- SvLEN_set(sv, SvLEN(sv) + delta);
- SvPV_set(sv, SvPVX(sv) - delta);
- Move(s, SvPVX(sv), SvCUR(sv)+1, char);
+ if (SvIVX(sv)) {
+ const char * const s = SvPVX_const(sv);
+#ifdef DEBUGGING
+ /* Validate the preceding buffer's sentinels to verify that no-one is
+ using it. */
+ const U8 *p = (const U8*) s;
+ const U8 *const real_start = p - SvIVX(sv);
+ while (p > real_start) {
+ --p;
+ assert (*p == (U8)PTR2UV(p));
+ }
+#endif
+ SvLEN_set(sv, SvLEN(sv) + SvIVX(sv));
+ SvPV_set(sv, SvPVX(sv) - SvIVX(sv));
+ SvIV_set(sv, 0);
+ Move(s, SvPVX(sv), SvCUR(sv)+1, char);
+ }
SvFLAGS(sv) &= ~SVf_OOK;
return 0;
}
@@ -3870,6 +3881,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
SvNV_set(dstr, SvNVX(sstr));
}
if (sflags & SVp_IOK) {
+ SvOOK_off(dstr);
SvIV_set(dstr, SvIVX(sstr));
/* Must do this otherwise some other overloaded use of 0x80000000
gets confused. I guess SVpbm_VALID */
@@ -4301,43 +4313,6 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
sv_unglob(sv);
}
-UV
-Perl_sv_read_offset(pTHX_ const SV *const sv) {
- U8 *p;
- UV delta = 0;
- U8 c;
-
- if (!SvOOK(sv))
- return 0;
- p = (U8*)SvPVX_const(sv);
- if (!p)
- return 0;
-
- c = *--p;
- delta = c & 0x7F;
- while ((c & 0x80)) {
- UV const last_delta = delta;
- delta <<= 7;
- if (delta < last_delta)
- Perl_croak(aTHX_ "panic: overflow in sv_read_offset from %"UVuf
- " to %"UVuf, last_delta, delta);
- c = *--p;
- delta |= c & 0x7F;
- }
-#ifdef DEBUGGING
- {
- /* Validate the preceding buffer's sentinels to verify that no-one is
- using it. */
- const U8 *const real_start = (U8 *) SvPVX_const(sv) - delta;
- while (p > real_start) {
- --p;
- assert (*p == (U8)PTR2UV(p));
- }
- }
-#endif
- return delta;
-}
-
/*
=for apidoc sv_chop
@@ -4356,11 +4331,6 @@ Perl_sv_chop(pTHX_ register SV *sv, register const char *ptr)
{
register STRLEN delta;
STRLEN max_delta;
- UV old_delta;
- U8 *p;
-#ifdef DEBUGGING
- const U8 *real_start;
-#endif
if (!ptr || !SvPOKp(sv))
return;
@@ -4378,6 +4348,9 @@ Perl_sv_chop(pTHX_ register SV *sv, register const char *ptr)
assert(ptr > SvPVX_const(sv));
SV_CHECK_THINKFIRST(sv);
+ if (SvTYPE(sv) < SVt_PVIV)
+ sv_upgrade(sv,SVt_PVIV);
+
if (delta > max_delta)
Perl_croak(aTHX_ "panic: sv_chop ptr=%p (was %p), start=%p, end=%p",
SvPVX_const(sv) + delta, ptr, SvPVX_const(sv),
@@ -4392,47 +4365,27 @@ Perl_sv_chop(pTHX_ register SV *sv, register const char *ptr)
Move(pvx,SvPVX(sv),len,char);
*SvEND(sv) = '\0';
}
+ SvIV_set(sv, 0);
+ /* Same SvOOK_on but SvOOK_on does a SvIOK_off
+ and we do that anyway inside the SvNIOK_off
+ */
SvFLAGS(sv) |= SVf_OOK;
- old_delta = 0;
- } else {
- old_delta = sv_read_offset(sv);
}
+ SvNIOK_off(sv);
SvLEN_set(sv, SvLEN(sv) - delta);
SvCUR_set(sv, SvCUR(sv) - delta);
SvPV_set(sv, SvPVX(sv) + delta);
-
- p = (U8 *)SvPVX_const(sv);
-
- delta += old_delta;
-
+ SvIV_set(sv, SvIVX(sv) + delta);
#ifdef DEBUGGING
- real_start = p - delta;
-#endif
-
- if (delta < 0x80) {
- *--p = (U8) delta;
- } else {
- /* Code lovingly ripped from pp_pack.c: */
- U8 buf[(sizeof(UV)*CHAR_BIT)/7+1];
- U8 *in = buf;
- STRLEN len;
- do {
- *in++ = (U8)((delta & 0x7f) | 0x80);
- delta >>= 7;
- } while (delta);
- buf[0] &= 0x7f; /* clear continue bit */
-
- len = in - buf;
- p -= len;
- Copy(buf, p, len, U8);
- }
-
-#ifdef DEBUGGING
- /* Fill the preceding buffer with sentinals to verify that no-one is
- using it. */
- while (p > real_start) {
- --p;
- *p = (U8)PTR2UV(p);
+ {
+ /* Fill the preceding buffer with sentinals to verify that no-one is
+ using it. */
+ U8 *p = (U8*) SvPVX(sv);
+ const U8 *const real_start = p - SvIVX(sv);
+ while (p > real_start) {
+ --p;
+ *p = (U8)PTR2UV(p);
+ }
}
#endif
}
@@ -5458,13 +5411,13 @@ Perl_sv_clear(pTHX_ register SV *sv)
case SVt_PVMG:
case SVt_PVNV:
case SVt_PVIV:
- case SVt_PV:
freescalar:
/* Don't bother with SvOOK_off(sv); as we're only going to free it. */
if (SvOOK(sv)) {
- SvPV_set(sv, SvPVX_mutable(sv) - sv_read_offset(sv));
+ SvPV_set(sv, SvPVX_mutable(sv) - SvIVX(sv));
/* Don't even bother with turning off the OOK flag. */
}
+ case SVt_PV:
case SVt_RV:
if (SvROK(sv)) {
SV * const target = SvRV(sv);