int
Perl_sv_backoff(pTHX_ register SV *sv)
{
- UV delta = sv_read_offset(sv);
+ STRLEN delta;
const char * const s = SvPVX_const(sv);
PERL_UNUSED_CONTEXT;
assert(SvOOK(sv));
assert(SvTYPE(sv) != SVt_PVHV);
assert(SvTYPE(sv) != SVt_PVAV);
+ SvOOK_offset(sv, delta);
+
SvLEN_set(sv, SvLEN(sv) + delta);
SvPV_set(sv, SvPVX(sv) - delta);
Move(s, SvPVX(sv), SvCUR(sv)+1, char);
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
void
Perl_sv_chop(pTHX_ register SV *sv, register const char *ptr)
{
- register STRLEN delta;
- UV old_delta;
+ STRLEN delta;
+ STRLEN old_delta;
U8 *p;
#ifdef DEBUGGING
const U8 *real_start;
SvFLAGS(sv) |= SVf_OOK;
old_delta = 0;
} else {
- old_delta = sv_read_offset(sv);
+ SvOOK_offset(sv, old_delta);
}
SvLEN_set(sv, SvLEN(sv) - delta);
SvCUR_set(sv, SvCUR(sv) - delta);
real_start = p - delta;
#endif
- if (delta < 0x80) {
+ assert(delta);
+ if (delta < 0x100) {
*--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);
+ *--p = 0;
+ p -= sizeof(STRLEN);
+ Copy((U8*)&delta, p, sizeof(STRLEN), U8);
}
#ifdef DEBUGGING
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));
+ STRLEN offset;
+ SvOOK_offset(sv, offset);
+ SvPV_set(sv, SvPVX_mutable(sv) - offset);
/* Don't even bother with turning off the OOK flag. */
}
if (SvROK(sv)) {