can tail call us and return true. */
return (char *) 1;
} else {
- return SvPV(buffer, *len);
+ assert(SvPOK(buffer));
+ if (len) {
+ *len = SvCUR(buffer);
+ }
+ return SvPVX(buffer);
}
}
}
}
if (!intro)
- cv_ckproto(cv, (GV*)dstr,
- SvPOK(sref) ? SvPVX_const(sref) : NULL);
+ cv_ckproto_len(cv, (GV*)dstr,
+ SvPOK(sref) ? SvPVX_const(sref) : NULL,
+ SvPOK(sref) ? SvCUR(sref) : 0);
}
GvCVGEN(dstr) = 0; /* Switch off cacheness. */
GvASSUMECV_on(dstr);
}
/*
-=for apidoc sv_usepvn
-
-Tells an SV to use C<ptr> to find its string value. Normally the string is
-stored inside the SV but sv_usepvn allows the SV to use an outside string.
-The C<ptr> should point to memory that was allocated by C<malloc>. The
-string length, C<len>, must be supplied. This function will realloc the
-memory pointed to by C<ptr>, so that pointer should not be freed or used by
-the programmer after giving it to sv_usepvn. Does not handle 'set' magic.
-See C<sv_usepvn_mg>.
+=for apidoc sv_usepvn_flags
+
+Tells an SV to use C<ptr> to find its string value. Normally the
+string is stored inside the SV but sv_usepvn allows the SV to use an
+outside string. The C<ptr> should point to memory that was allocated
+by C<malloc>. The string length, C<len>, must be supplied. By default
+this function will realloc (i.e. move) the memory pointed to by C<ptr>,
+so that pointer should not be freed or used by the programmer after
+giving it to sv_usepvn, and neither should any pointers from "behind"
+that pointer (e.g. ptr + 1) be used.
+
+If C<flags> & SV_SMAGIC is true, will call SvSETMAGIC. If C<flags> &
+SV_HAS_TRAILING_NUL is true, then C<ptr[len]> must be NUL, and the realloc
+will be skipped. (i.e. the buffer is actually at least 1 byte longer than
+C<len>, and already meets the requirements for storing in C<SvPVX>)
=cut
*/
void
-Perl_sv_usepvn(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
+Perl_sv_usepvn_flags(pTHX_ SV *sv, char *ptr, STRLEN len, U32 flags)
{
dVAR;
STRLEN allocate;
SvUPGRADE(sv, SVt_PV);
if (!ptr) {
(void)SvOK_off(sv);
+ if (flags & SV_SMAGIC)
+ SvSETMAGIC(sv);
return;
}
if (SvPVX_const(sv))
SvPV_free(sv);
- allocate = PERL_STRLEN_ROUNDUP(len + 1);
- ptr = saferealloc (ptr, allocate);
+ if (flags & SV_HAS_TRAILING_NUL)
+ assert(ptr[len] == '\0');
+
+ allocate = (flags & SV_HAS_TRAILING_NUL)
+ ? len + 1: PERL_STRLEN_ROUNDUP(len + 1);
+ if (flags & SV_HAS_TRAILING_NUL) {
+ /* It's long enough - do nothing.
+ Specfically Perl_newCONSTSUB is relying on this. */
+ } else {
+#ifdef DEBUGGING
+ /* Force a move to shake out bugs in callers. */
+ char *new_ptr = safemalloc(allocate);
+ Copy(ptr, new_ptr, len, char);
+ PoisonFree(ptr,len,char);
+ Safefree(ptr);
+ ptr = new_ptr;
+#else
+ ptr = saferealloc (ptr, allocate);
+#endif
+ }
SvPV_set(sv, ptr);
SvCUR_set(sv, len);
SvLEN_set(sv, allocate);
- *SvEND(sv) = '\0';
+ if (!(flags & SV_HAS_TRAILING_NUL)) {
+ *SvEND(sv) = '\0';
+ }
(void)SvPOK_only_UTF8(sv); /* validate pointer */
SvTAINT(sv);
-}
-
-/*
-=for apidoc sv_usepvn_mg
-
-Like C<sv_usepvn>, but also handles 'set' magic.
-
-=cut
-*/
-
-void
-Perl_sv_usepvn_mg(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
-{
- sv_usepvn(sv,ptr,len);
- SvSETMAGIC(sv);
+ if (flags & SV_SMAGIC)
+ SvSETMAGIC(sv);
}
#ifdef PERL_OLD_COPY_ON_WRITE
return sv;
}
/* This will be overwhelminly the most common case. */
- return newSVpvn_share(HEK_KEY(hek),
- (HEK_UTF8(hek) ? -HEK_LEN(hek) : HEK_LEN(hek)),
- HEK_HASH(hek));
+ {
+ /* Inline most of newSVpvn_share(), because share_hek_hek() is far
+ more efficient than sharepvn(). */
+ SV *sv;
+
+ new_SV(sv);
+ sv_upgrade(sv, SVt_PV);
+ SvPV_set(sv, (char *)HEK_KEY(share_hek_hek(hek)));
+ SvCUR_set(sv, HEK_LEN(hek));
+ SvLEN_set(sv, 0);
+ SvREADONLY_on(sv);
+ SvFAKE_on(sv);
+ SvPOK_on(sv);
+ if (HEK_UTF8(hek))
+ SvUTF8_on(sv);
+ return sv;
+ }
}
}
dVAR;
register SV *sv;
bool is_utf8 = FALSE;
+ const char *const orig_src = src;
+
if (len < 0) {
STRLEN tmplen = -len;
is_utf8 = TRUE;
SvPOK_on(sv);
if (is_utf8)
SvUTF8_on(sv);
+ if (src != orig_src)
+ Safefree(src);
return sv;
}
break;
case SAVEt_HV: /* hash reference */
case SAVEt_AV: /* array reference */
- av = (AV*)POPPTR(ss,ix);
- TOPPTR(nss,ix) = sv_dup_inc(av, param);
+ sv = POPPTR(ss,ix);
+ TOPPTR(nss,ix) = sv_dup_inc(sv, param);
gv = (GV*)POPPTR(ss,ix);
TOPPTR(nss,ix) = gv_dup(gv, param);
break;
i = POPINT(ss,ix);
TOPINT(nss,ix) = i;
ptr = POPPTR(ss,ix);
- TOPPTR(nss,ix) = Perl_refcounted_he_dup(aTHX_ ptr, param);
+ if (ptr) {
+ HINTS_REFCNT_LOCK;
+ ((struct refcounted_he *)ptr)->refcounted_he_refcnt++;
+ HINTS_REFCNT_UNLOCK;
+ }
+ TOPPTR(nss,ix) = ptr;
if (i & HINT_LOCALIZE_HH) {
hv = (HV*)POPPTR(ss,ix);
TOPPTR(nss,ix) = hv_dup_inc(hv, param);
= pv_dup(old_state->re_state_bostr);
new_state->re_state_reginput
= pv_dup(old_state->re_state_reginput);
- new_state->re_state_regbol
- = pv_dup(old_state->re_state_regbol);
new_state->re_state_regeol
= pv_dup(old_state->re_state_regeol);
new_state->re_state_regstartp
new_state->re_state_reglastcloseparen
= any_dup(old_state->re_state_reglastcloseparen,
proto_perl);
- new_state->re_state_regtill
- = pv_dup(old_state->re_state_regtill);
/* XXX This just has to be broken. The old save_re_context
code did SAVEGENERICPV(PL_reg_start_tmp);
PL_reg_start_tmp is char **.
/* I assume that it only ever "worked" because no-one called
(pseudo)fork while the regexp engine had re-entered itself.
*/
- new_state->re_state_reg_call_cc
- = any_dup(old_state->re_state_reg_call_cc, proto_perl);
- new_state->re_state_reg_re
- = any_dup(old_state->re_state_reg_re, proto_perl);
- new_state->re_state_reg_ganch
- = pv_dup(old_state->re_state_reg_ganch);
- new_state->re_state_reg_sv
- = sv_dup(old_state->re_state_reg_sv, param);
#ifdef PERL_OLD_COPY_ON_WRITE
new_state->re_state_nrs
= sv_dup(old_state->re_state_nrs, param);
#endif
break;
}
+ case SAVEt_COMPILE_WARNINGS:
+ ptr = POPPTR(ss,ix);
+ TOPPTR(nss,ix) = DUP_WARNINGS((STRLEN*)ptr);
+ break;
default:
Perl_croak(aTHX_ "panic: ss_dup inconsistency (%"IVdf")", (IV) i);
}
ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling);
- if (!specialWARN(PL_compiling.cop_warnings))
- PL_compiling.cop_warnings = sv_dup_inc(PL_compiling.cop_warnings, param);
+ PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
if (!specialCopIO(PL_compiling.cop_io))
PL_compiling.cop_io = sv_dup_inc(PL_compiling.cop_io, param);
- PL_compiling.cop_hints
- = Perl_refcounted_he_dup(aTHX_ PL_compiling.cop_hints, param);
+ if (PL_compiling.cop_hints) {
+ HINTS_REFCNT_LOCK;
+ PL_compiling.cop_hints->refcounted_he_refcnt++;
+ HINTS_REFCNT_UNLOCK;
+ }
PL_curcop = (COP*)any_dup(proto_perl->Tcurcop, proto_perl);
/* pseudo environmental stuff */