This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
toke.c: In sublex_push use multi_close to detect here-doc
[perl5.git] / pp_ctl.c
index b7b3598..7fd27f8 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2776,7 +2776,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac
     return 0;
 }
 
-PP(pp_goto)
+PP(pp_goto) /* also pp_dump */
 {
     dVAR; dSP;
     OP *retop = NULL;
@@ -2791,6 +2791,8 @@ PP(pp_goto)
     static const char* const must_have_label = "goto must have label";
 
     if (PL_op->op_flags & OPf_STACKED) {
+        /* goto EXPR  or  goto &foo */
+
        SV * const sv = POPs;
        SvGETMAGIC(sv);
 
@@ -2893,31 +2895,27 @@ PP(pp_goto)
                OP* const retop = cx->blk_sub.retop;
                SV **newsp;
                I32 gimme;
-               const SSize_t items = AvFILLp(arg) + 1;
+               const SSize_t items = arg ? AvFILLp(arg) + 1 : 0;
                SV** mark;
 
                 PERL_UNUSED_VAR(newsp);
                 PERL_UNUSED_VAR(gimme);
 
                /* put GvAV(defgv) back onto stack */
-               EXTEND(SP, items+1); /* @_ could have been extended. */
-               Copy(AvARRAY(arg), SP + 1, items, SV*);
+               if (items) {
+                   EXTEND(SP, items+1); /* @_ could have been extended. */
+                   Copy(AvARRAY(arg), SP + 1, items, SV*);
+               }
                mark = SP;
                SP += items;
-               if (AvREAL(arg)) {
-                   I32 index;
+               if (items && AvREAL(arg)) {
+                   SSize_t index;
                    for (index=0; index<items; index++)
                        if (SP[-index])
                            SvREFCNT_inc_void_NN(sv_2mortal(SP[-index]));
                        else {
-                           SV * const lv =
-                               sv_2mortal(newSV_type(SVt_PVLV));
-                           SP[-index] = lv;
-                           LvTYPE(lv) = 'y';
-                           sv_magic(lv,NULL,PERL_MAGIC_defelem,NULL,0);
-                           LvTARG(lv) = SvREFCNT_inc_simple_NN(arg);
-                           LvSTARGOFF(lv) = AvFILLp(arg) - index;
-                           LvTARGLEN(lv) = 1;
+                           SP[-index] = sv_2mortal(newSVavdefelem(arg,
+                                                AvFILLp(arg) - index, 1));
                        }
                }
                SvREFCNT_dec(arg);
@@ -2992,11 +2990,13 @@ PP(pp_goto)
            }
        }
        else {
+            /* goto EXPR */
            label       = SvPV_nomg_const(sv, label_len);
             label_flags = SvUTF8(sv);
        }
     }
     else if (!(PL_op->op_flags & OPf_SPECIAL)) {
+        /* goto LABEL  or  dump LABEL */
        label       = cPVOP->op_pv;
         label_flags = (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0;
         label_len   = strlen(label);