summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c40
1 files changed, 14 insertions, 26 deletions
diff --git a/pp.c b/pp.c
index a6b30412b5..cc4cb59f7d 100644
--- a/pp.c
+++ b/pp.c
@@ -3477,41 +3477,29 @@ PP(pp_vec)
SV * const src = POPs;
const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
SV * ret;
- UV retuv = 0;
- STRLEN offset;
+ UV retuv;
+ STRLEN offset = 0;
+ char errflags = 0;
/* extract a STRLEN-ranged integer value from offsetsv into offset,
- * or die trying */
+ * or flag that its out of range */
{
IV iv = SvIV(offsetsv);
/* avoid a large UV being wrapped to a negative value */
- if (SvIOK_UV(offsetsv) && SvUVX(offsetsv) > (UV)IV_MAX) {
- if (!lvalue)
- goto return_val; /* out of range: return 0 */
- Perl_croak_nocontext("Out of memory!");
- }
-
- if (iv < 0) {
- if (!lvalue)
- goto return_val; /* out of range: return 0 */
- Perl_croak_nocontext("Negative offset to vec in lvalue context");
- }
-
+ if (SvIOK_UV(offsetsv) && SvUVX(offsetsv) > (UV)IV_MAX)
+ errflags = 4; /* out of range */
+ else if (iv < 0)
+ errflags = (1|4); /* negative offset, out of range */
#if PTRSIZE < IVSIZE
- if (iv > Size_t_MAX) {
- if (!lvalue)
- goto return_val; /* out of range: return 0 */
- Perl_croak_nocontext("Out of memory!");
- }
+ else if (iv > Size_t_MAX)
+ errflags = 4; /* out of range */
#endif
-
- offset = (STRLEN)iv;
+ else
+ offset = (STRLEN)iv;
}
- retuv = do_vecget(src, offset, size);
-
- return_val:
+ retuv = errflags ? 0 : do_vecget(src, offset, size);
if (lvalue) { /* it's an lvalue! */
ret = sv_2mortal(newSV_type(SVt_PVLV)); /* Not TARG RT#67838 */
@@ -3520,6 +3508,7 @@ PP(pp_vec)
LvTARG(ret) = SvREFCNT_inc_simple(src);
LvTARGOFF(ret) = offset;
LvTARGLEN(ret) = size;
+ LvFLAGS(ret) = errflags;
}
else {
dTARGET;
@@ -3527,7 +3516,6 @@ PP(pp_vec)
ret = TARG;
}
-
sv_setuv(ret, retuv);
if (!lvalue)
SvSETMAGIC(ret);