File Coverage

Alias.xs
Criterion Covered Total %
statement 1071 1207 88.7
branch 687 1096 62.6
condition n/a
subroutine n/a
pod n/a
total 1758 2303 76.3


line stmt bran cond sub pod time code
1             /* Copyright (C) 2003, 2004, 2006, 2007 Matthijs van Duin
2             *
3             * Copyright (C) 2010, 2011, 2013, 2015, 2017
4             * Andrew Main (Zefram)
5             *
6             * Parts from perl, which is Copyright (C) 1991-2013 Larry Wall and others
7             *
8             * You may distribute under the same terms as perl itself, which is either
9             * the GNU General Public License or the Artistic License.
10             */
11              
12             #define PERL_CORE
13             #define PERL_NO_GET_CONTEXT
14             #include "EXTERN.h"
15             #include "config.h"
16             #undef USE_DTRACE
17             #include "perl.h"
18             #undef PERL_CORE
19             #include "XSUB.h"
20              
21              
22             #ifdef USE_5005THREADS
23             #error "5.005 threads not supported by Data::Alias"
24             #endif
25              
26              
27             #ifndef PERL_COMBI_VERSION
28             #define PERL_COMBI_VERSION (PERL_REVISION * 1000000 + PERL_VERSION * 1000 + \
29             PERL_SUBVERSION)
30             #endif
31              
32             #ifndef cBOOL
33             #define cBOOL(x) ((bool)!!(x))
34             #endif
35              
36              
37             #ifndef G_LIST
38             #define G_LIST G_ARRAY
39             #endif
40              
41              
42             #ifndef RenewOpc
43             #if defined(PL_OP_SLAB_ALLOC) || (PERL_COMBI_VERSION >= 5017002)
44             #define RenewOpc(m,v,n,t,c) \
45             STMT_START { \
46             t *tMp_; \
47             NewOp(m,tMp_,n,t); \
48             Copy(v,tMp_,n,t); \
49             FreeOp(v); \
50             v = (c*) tMp_; \
51             } STMT_END
52             #else
53             #if (PERL_COMBI_VERSION >= 5009004)
54             #define RenewOpc(m,v,n,t,c) \
55             (v = (MEM_WRAP_CHECK_(n,t) \
56             (c*)PerlMemShared_realloc(v, (n)*sizeof(t))))
57             #else
58             #define RenewOpc(m,v,n,t,c) \
59             Renewc(v,n,t,c)
60             #endif
61             #endif
62             #endif
63              
64             #ifndef RenewOp
65             #define RenewOp(m,v,n,t) \
66             RenewOpc(m,v,n,t,t)
67             #endif
68              
69              
70             #ifdef avhv_keys
71             #define DA_FEATURE_AVHV 1
72             #endif
73              
74             #if (PERL_COMBI_VERSION >= 5009003)
75             #define PL_no_helem PL_no_helem_sv
76             #endif
77              
78             #ifndef SvPVX_const
79             #define SvPVX_const SvPVX
80             #endif
81              
82             #ifndef SvREFCNT_inc_NN
83             #define SvREFCNT_inc_NN SvREFCNT_inc
84             #endif
85             #ifndef SvREFCNT_inc_simple_NN
86             #define SvREFCNT_inc_simple_NN SvREFCNT_inc_NN
87             #endif
88             #ifndef SvREFCNT_inc_simple_void_NN
89             #define SvREFCNT_inc_simple_void_NN SvREFCNT_inc_simple_NN
90             #endif
91              
92             #ifndef GvGP_set
93             #define GvGP_set(gv, val) (GvGP(gv) = (val))
94             #endif
95             #ifndef GvCV_set
96             #define GvCV_set(gv, val) (GvCV(gv) = (val))
97             #endif
98              
99             #if (PERL_COMBI_VERSION >= 5009003)
100             #define DA_FEATURE_MULTICALL 1
101             #endif
102              
103             #if (PERL_COMBI_VERSION >= 5009002)
104             #define DA_FEATURE_RETOP 1
105             #endif
106              
107             #define INT2SIZE(x) ((MEM_SIZE)(SSize_t)(x))
108             #define DA_ARRAY_MAXIDX ((IV) (INT2SIZE(-1) / (2 * sizeof(SV *))) )
109              
110             #ifndef Nullsv
111             #define Nullsv ((SV*)NULL)
112             #endif
113              
114             #ifndef Nullop
115             #define Nullop ((OP*)NULL)
116             #endif
117              
118             #ifndef lex_end
119             #define lex_end() ((void) 0)
120             #endif
121              
122             #ifndef op_lvalue
123             #define op_lvalue(o, t) mod(o, t)
124             #endif
125              
126             #define DA_HAVE_OP_PADRANGE (PERL_COMBI_VERSION >= 5017006)
127              
128             #if DA_HAVE_OP_PADRANGE
129             #define IS_PUSHMARK_OR_PADRANGE(op) \
130             ((op)->op_type == OP_PUSHMARK || (op)->op_type == OP_PADRANGE)
131             #else
132             #define IS_PUSHMARK_OR_PADRANGE(op) ((op)->op_type == OP_PUSHMARK)
133             #endif
134              
135             #if (PERL_COMBI_VERSION < 5010001)
136             typedef unsigned Optype;
137             #endif
138              
139             #ifndef OpMORESIB_set
140             #define OpMORESIB_set(o, sib) ((o)->op_sibling = (sib))
141             #define OpLASTSIB_set(o, parent) ((o)->op_sibling = NULL)
142             #define OpMAYBESIB_set(o, sib, parent) ((o)->op_sibling = (sib))
143             #endif
144             #ifndef OpSIBLING
145             #define OpHAS_SIBLING(o) (cBOOL((o)->op_sibling))
146             #define OpSIBLING(o) (0 + (o)->op_sibling)
147             #endif
148              
149             #if (PERL_COMBI_VERSION < 5009003)
150             typedef OP *(*Perl_check_t)(pTHX_ OP *);
151             #endif
152              
153             #ifndef wrap_op_checker
154             #define wrap_op_checker(c,n,o) THX_wrap_op_checker(aTHX_ c,n,o)
155             static void THX_wrap_op_checker(pTHX_ Optype opcode,
156             Perl_check_t new_checker, Perl_check_t *old_checker_p)
157             {
158             if(*old_checker_p) return;
159             OP_REFCNT_LOCK;
160             if(!*old_checker_p) {
161             *old_checker_p = PL_check[opcode];
162             PL_check[opcode] = new_checker;
163             }
164             OP_REFCNT_UNLOCK;
165             }
166             #endif
167              
168             #define DA_HAVE_LEX_KNOWNEXT (PERL_COMBI_VERSION < 5025001)
169              
170             #if (PERL_COMBI_VERSION >= 5011000) && !defined(SVt_RV)
171             #define SVt_RV SVt_IV
172             #endif
173              
174             #ifndef IS_PADGV
175             #ifdef USE_ITHREADS
176             #define IS_PADGV(v) ((v) && SvTYPE(v) == SVt_PVGV)
177             #else
178             #define IS_PADGV(v) 0
179             #endif
180             #endif
181              
182             #ifndef PadnamelistARRAY
183             #define PadnamelistARRAY(pnl) AvARRAY(pnl)
184             #endif
185              
186             #ifndef PadnameOUTER
187             #define PadnameOUTER(pn) (!!SvFAKE(pn))
188             #endif
189              
190             #if (PERL_COMBI_VERSION >= 5006000) && (PERL_COMBI_VERSION < 5011000)
191             #define case_OP_SETSTATE_ case OP_SETSTATE:
192             #else
193             #define case_OP_SETSTATE_
194             #endif
195              
196             #if (PERL_COMBI_VERSION >= 5011002)
197             static char const msg_no_symref[] =
198             "Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use";
199             #else
200             #define msg_no_symref PL_no_symref
201             #endif
202              
203             #if (PERL_COMBI_VERSION >= 5009005)
204             #ifdef PERL_MAD
205             #error "Data::Alias doesn't support Misc Attribute Decoration yet"
206             #endif
207             #if DA_HAVE_LEX_KNOWNEXT
208             #define PL_lex_defer (PL_parser->lex_defer)
209             #endif
210             #if (PERL_COMBI_VERSION < 5021004)
211             #define PL_lex_expect (PL_parser->lex_expect)
212             #endif
213             #define PL_linestr (PL_parser->linestr)
214             #define PL_expect (PL_parser->expect)
215             #define PL_bufptr (PL_parser->bufptr)
216             #define PL_oldbufptr (PL_parser->oldbufptr)
217             #define PL_oldoldbufptr (PL_parser->oldoldbufptr)
218             #define PL_bufend (PL_parser->bufend)
219             #define PL_last_uni (PL_parser->last_uni)
220             #define PL_last_lop (PL_parser->last_lop)
221             #define PL_lex_state (PL_parser->lex_state)
222             #define PL_nexttoke (PL_parser->nexttoke)
223             #define PL_nexttype (PL_parser->nexttype)
224             #define PL_tokenbuf (PL_parser->tokenbuf)
225             #define PL_yylval (PL_parser->yylval)
226             #elif (PERL_COMBI_VERSION >= 5009001)
227             #define PL_yylval (*PL_yylvalp)
228             #endif
229              
230              
231             #define OPpALIASAV 1
232             #define OPpALIASHV 2
233             #define OPpALIAS (OPpALIASAV | OPpALIASHV)
234              
235             #define OPpUSEFUL OPpLVAL_INTRO
236              
237             #define MOD(op) op_lvalue((op), OP_GREPSTART)
238              
239             #ifndef SVs_PADBUSY
240             #define SVs_PADBUSY 0
241             #endif
242             #define SVs_PADFLAGS (SVs_PADBUSY|SVs_PADMY|SVs_PADTMP)
243              
244             #ifdef pp_dorassign
245             #define DA_HAVE_OP_DORASSIGN 1
246             #else
247             #define DA_HAVE_OP_DORASSIGN (PERL_COMBI_VERSION >= 5009000)
248             #endif
249              
250             #define DA_TIED_ERR "Can't %s alias %s tied %s"
251             #define DA_ODD_HASH_ERR "Odd number of elements in hash assignment"
252             #define DA_TARGET_ERR "Unsupported alias target"
253             #define DA_TARGET_ERR_AT "Unsupported alias target at %s line %"UVuf"\n"
254             #define DA_DEREF_ERR "Can't deref string (\"%.32s\")"
255             #define DA_OUTER_ERR "Aliasing of outer lexical variable has limited scope"
256              
257             #define _PUSHaa(a1,a2) PUSHs((SV*)(Size_t)(a1));PUSHs((SV*)(Size_t)(a2))
258             #define PUSHaa(a1,a2) STMT_START { _PUSHaa(a1,a2); } STMT_END
259             #define XPUSHaa(a1,a2) STMT_START { EXTEND(sp,2); _PUSHaa(a1,a2); } STMT_END
260              
261             #define DA_ALIAS_PAD ((Size_t) -1)
262             #define DA_ALIAS_RV ((Size_t) -2)
263             #define DA_ALIAS_GV ((Size_t) -3)
264             #define DA_ALIAS_AV ((Size_t) -4)
265             #define DA_ALIAS_HV ((Size_t) -5)
266              
267             STATIC OP *(*da_old_ck_rv2cv)(pTHX_ OP *op);
268             STATIC OP *(*da_old_ck_entersub)(pTHX_ OP *op);
269             #if (PERL_COMBI_VERSION >= 5021007)
270             STATIC OP *(*da_old_ck_aelem)(pTHX_ OP *op);
271             STATIC OP *(*da_old_ck_helem)(pTHX_ OP *op);
272             #endif
273              
274             #ifdef USE_ITHREADS
275              
276             #define DA_GLOBAL_KEY "Data::Alias::_global"
277             #define DA_FETCH(create) hv_fetch(PL_modglobal, DA_GLOBAL_KEY, \
278             sizeof(DA_GLOBAL_KEY) - 1, create)
279             #define DA_ACTIVE ((_dap = DA_FETCH(FALSE)) && (_da = *_dap))
280             #define DA_INIT STMT_START { _dap = DA_FETCH(TRUE); _da = *_dap; \
281             sv_upgrade(_da, SVt_PVLV); LvTYPE(_da) = 't'; } STMT_END
282              
283             #define dDA SV *_da, **_dap
284             #define dDAforce SV *_da = *DA_FETCH(FALSE)
285              
286             #define da_inside (*(I32 *) &SvIVX(_da))
287             #define da_iscope (*(PERL_CONTEXT **) &SvPVX(_da))
288             #define da_cv (*(CV **) &LvTARGOFF(_da))
289             #define da_cvc (*(CV **) &LvTARGLEN(_da))
290              
291             #else
292              
293             #define dDA dNOOP
294             #define dDAforce dNOOP
295             #define DA_ACTIVE 42
296             #define DA_INIT
297              
298             STATIC CV *da_cv, *da_cvc;
299             STATIC I32 da_inside;
300             STATIC PERL_CONTEXT *da_iscope;
301              
302             #endif
303              
304             STATIC void (*da_old_peepp)(pTHX_ OP *);
305              
306 0           STATIC OP *da_tag_rv2cv(pTHX) { return NORMAL; }
307 0           STATIC OP *da_tag_list(pTHX) { return NORMAL; }
308 0           STATIC OP *da_tag_entersub(pTHX) { return NORMAL; }
309             #if (PERL_COMBI_VERSION >= 5031002)
310             STATIC OP *da_tag_enter(pTHX) { return NORMAL; }
311             #endif
312              
313             STATIC void da_peep(pTHX_ OP *o);
314             STATIC void da_peep2(pTHX_ OP *o);
315              
316 33           STATIC SV *da_fetch(pTHX_ SV *a1, SV *a2) {
317 33           switch ((Size_t) a1) {
318             case DA_ALIAS_PAD:
319 13           return PL_curpad[(Size_t) a2];
320             case DA_ALIAS_RV:
321 8 50         if (SvTYPE(a2) == SVt_PVGV)
322 8           a2 = GvSV(a2);
323 0 0         else if (!SvROK(a2) || !(a2 = SvRV(a2))
    0          
324 0 0         || (SvTYPE(a2) > SVt_PVLV && SvTYPE(a2) != SVt_PVGV))
    0          
325 0           Perl_croak(aTHX_ "Not a SCALAR reference");
326             case DA_ALIAS_GV:
327 8           return a2;
328             case DA_ALIAS_AV:
329             case DA_ALIAS_HV:
330 0           break;
331             default:
332 12           switch (SvTYPE(a1)) {
333             SV **svp;
334             HE *he;
335             case SVt_PVAV:
336 8           svp = av_fetch((AV *) a1, (Size_t) a2, FALSE);
337 8 50         return svp ? *svp : &PL_sv_undef;
338             case SVt_PVHV:
339 4           he = hv_fetch_ent((HV *) a1, a2, FALSE, 0);
340 4 50         return he ? HeVAL(he) : &PL_sv_undef;
341             default:
342             /* suppress warning */ ;
343             }
344             }
345 0           Perl_croak(aTHX_ DA_TARGET_ERR);
346             return NULL; /* suppress warning on win32 */
347             }
348              
349             #define PREP_ALIAS_INC(sV) \
350             STMT_START { \
351             if (SvPADTMP(sV) && !IS_PADGV(sV)) { \
352             sV = newSVsv(sV); \
353             SvREADONLY_on(sV); \
354             } else { \
355             switch (SvTYPE(sV)) { \
356             case SVt_PVLV: \
357             if (LvTYPE(sV) == 'y') { \
358             if (LvTARGLEN(sV)) \
359             vivify_defelem(sV); \
360             sV = LvTARG(sV); \
361             if (!sV) \
362             sV = &PL_sv_undef; \
363             } \
364             break; \
365             case SVt_PVAV: \
366             if (!AvREAL((AV *) sV) && AvREIFY((AV *) sV)) \
367             av_reify((AV *) sV); \
368             break; \
369             default: \
370             /* suppress warning */ ; \
371             } \
372             SvTEMP_off(sV); \
373             SvREFCNT_inc_simple_void_NN(sV); \
374             } \
375             } STMT_END
376              
377 1           STATIC void da_restore_gvcv(pTHX_ void *gv_v) {
378 1           GV *gv = (GV*)gv_v;
379 1           CV *restcv = (CV *) SSPOPPTR;
380 1           CV *oldcv = GvCV(gv);
381 1           GvCV_set(gv, restcv);
382 1           SvREFCNT_dec(oldcv);
383 1           SvREFCNT_dec((SV *) gv);
384 1           }
385              
386 173           STATIC void da_alias(pTHX_ SV *a1, SV *a2, SV *value) {
387 173 100         PREP_ALIAS_INC(value);
    50          
    50          
    50          
    100          
    50          
388 173 100         if ((Size_t) a1 == DA_ALIAS_PAD) {
389 32           SV *old = PL_curpad[(Size_t) a2];
390 32           PL_curpad[(Size_t) a2] = value;
391 32           SvFLAGS(value) |= (SvFLAGS(old) & SVs_PADFLAGS);
392 32 100         if (old != &PL_sv_undef)
393 18           SvREFCNT_dec(old);
394 32           return;
395             }
396 141           switch ((Size_t) a1) {
397             SV **svp;
398             GV *gv;
399             case DA_ALIAS_RV:
400 91 100         if (SvTYPE(a2) == SVt_PVGV) {
401 84           sv_2mortal(value);
402 84           goto globassign;
403             }
404 7           value = newRV_noinc(value);
405 7           goto refassign;
406             case DA_ALIAS_GV:
407 14 100         if (!SvROK(value)) {
408             refassign:
409 12 50         SvSetMagicSV(a2, value);
    50          
410 12           SvREFCNT_dec(value);
411 12           return;
412             }
413 9           value = SvRV(sv_2mortal(value));
414             globassign:
415 93           gv = (GV *) a2;
416             #ifdef GV_UNIQUE_CHECK
417             if (GvUNIQUE(gv))
418             Perl_croak(aTHX_ PL_no_modify);
419             #endif
420 93           switch (SvTYPE(value)) {
421             CV *oldcv;
422             case SVt_PVCV:
423 1           oldcv = GvCV(gv);
424 1 50         if (oldcv != (CV *) value) {
425 1 50         if (GvCVGEN(gv)) {
426 0           GvCV_set(gv, NULL);
427 0           GvCVGEN(gv) = 0;
428 0           SvREFCNT_dec((SV *) oldcv);
429 0           oldcv = NULL;
430             }
431 1           PL_sub_generation++;
432             }
433 1           GvMULTI_on(gv);
434 1 50         if (GvINTRO(gv)) {
435 1           SvREFCNT_inc_simple_void_NN((SV *) gv);
436 1           SvREFCNT_inc_simple_void_NN(value);
437 1           GvINTRO_off(gv);
438 1 50         SSCHECK(1);
439 1           SSPUSHPTR((SV *) oldcv);
440 1           SAVEDESTRUCTOR_X(da_restore_gvcv, (void*)gv);
441 1           GvCV_set(gv, (CV*)value);
442             } else {
443 0           SvREFCNT_inc_simple_void_NN(value);
444 0           GvCV_set(gv, (CV*)value);
445 0           SvREFCNT_dec((SV *) oldcv);
446             }
447 1           return;
448 10           case SVt_PVAV: svp = (SV **) &GvAV(gv); break;
449 10           case SVt_PVHV: svp = (SV **) &GvHV(gv); break;
450 1           case SVt_PVFM: svp = (SV **) &GvFORM(gv); break;
451 1           case SVt_PVIO: svp = (SV **) &GvIOp(gv); break;
452 70           default: svp = &GvSV(gv);
453             }
454 92           GvMULTI_on(gv);
455 92 100         if (GvINTRO(gv)) {
456 5           GvINTRO_off(gv);
457 5           SAVEGENERICSV(*svp);
458 5           *svp = SvREFCNT_inc_simple_NN(value);
459             } else {
460 87           SV *old = *svp;
461 87           *svp = SvREFCNT_inc_simple_NN(value);
462 87           SvREFCNT_dec(old);
463             }
464 92           return;
465             case DA_ALIAS_AV:
466             case DA_ALIAS_HV:
467 0           break;
468             default:
469 36           switch (SvTYPE(a1)) {
470             case SVt_PVAV:
471 21 50         if (!av_store((AV *) a1, (Size_t) a2, value))
472 0           SvREFCNT_dec(value);
473 21           return;
474             case SVt_PVHV:
475 15 100         if (value == &PL_sv_undef) {
476 1           (void) hv_delete_ent((HV *) a1, a2,
477             G_DISCARD, 0);
478             } else {
479 14 50         if (!hv_store_ent((HV *) a1, a2, value, 0))
480 0           SvREFCNT_dec(value);
481             }
482 15           return;
483             default:
484             /* suppress warning */ ;
485             }
486             }
487 0           SvREFCNT_dec(value);
488 0           Perl_croak(aTHX_ DA_TARGET_ERR);
489             }
490              
491 14           STATIC void da_unlocalize_gvar(pTHX_ void *gp_v) {
492 14           GP *gp = (GP*) gp_v;
493 14           SV *value = (SV *) SSPOPPTR;
494 14           SV **sptr = (SV **) SSPOPPTR;
495 14           SV *old = *sptr;
496 14           *sptr = value;
497 14           SvREFCNT_dec(old);
498              
499 14 100         if (gp->gp_refcnt > 1) {
500 11           --gp->gp_refcnt;
501             } else {
502 3           SV *gv = newSV(0);
503 3           sv_upgrade(gv, SVt_PVGV);
504 3           SvSCREAM_on(gv);
505 3           GvGP_set(gv, gp);
506 3           sv_free(gv);
507             }
508 14           }
509              
510 14           STATIC void da_localize_gvar(pTHX_ GP *gp, SV **sptr) {
511 14 50         SSCHECK(2);
512 14           SSPUSHPTR(sptr);
513 14           SSPUSHPTR(*sptr);
514 14           SAVEDESTRUCTOR_X(da_unlocalize_gvar, (void*)gp);
515 14           ++gp->gp_refcnt;
516 14           *sptr = Nullsv;
517 14           }
518              
519 99           STATIC SV *da_refgen(pTHX_ SV *sv) {
520             SV *rv;
521 99 50         PREP_ALIAS_INC(sv);
    0          
    0          
    0          
    50          
    0          
522 99           rv = sv_newmortal();
523 99           sv_upgrade(rv, SVt_RV);
524 99           SvRV(rv) = sv;
525 99           SvROK_on(rv);
526 99           SvREADONLY_on(rv);
527 99           return rv;
528             }
529              
530 69           STATIC OP *DataAlias_pp_srefgen(pTHX) {
531 69           dSP;
532 69           SETs(da_refgen(aTHX_ TOPs));
533 69           RETURN;
534             }
535              
536 4           STATIC OP *DataAlias_pp_refgen(pTHX) {
537 4           dSP; dMARK;
538 4 50         if (GIMME_V != G_LIST) {
    50          
539 4           ++MARK;
540 4 50         *MARK = da_refgen(aTHX_ MARK <= SP ? TOPs : &PL_sv_undef);
541 4           SP = MARK;
542             } else {
543 0 0         EXTEND_MORTAL(SP - MARK);
544 0 0         while (++MARK <= SP)
545 0           *MARK = da_refgen(aTHX_ *MARK);
546             }
547 4           RETURN;
548             }
549              
550 13           STATIC OP *DataAlias_pp_anonlist(pTHX) {
551 13           dSP; dMARK;
552 13           I32 i = SP - MARK;
553 13           AV *av = newAV();
554             SV **svp, *sv;
555 13           av_extend(av, i - 1);
556 13           AvFILLp(av) = i - 1;
557 13           svp = AvARRAY(av);
558 32 100         while (i--)
559 19           SvTEMP_off(svp[i] = SvREFCNT_inc_NN(POPs));
560 13 100         if (PL_op->op_flags & OPf_SPECIAL) {
561 9           sv = da_refgen(aTHX_ (SV *) av);
562 9           SvREFCNT_dec((SV *) av);
563             } else {
564 4           sv = sv_2mortal((SV *) av);
565             }
566 13 50         XPUSHs(sv);
567 13           RETURN;
568             }
569              
570 22           STATIC OP *DataAlias_pp_anonhash(pTHX) {
571 22           dSP; dMARK; dORIGMARK;
572 22           HV *hv = (HV *) newHV();
573             SV *sv;
574 53 100         while (MARK < SP) {
575 32           SV *key = *++MARK;
576 32           SV *val = &PL_sv_undef;
577 32 100         if (MARK < SP)
578 30           SvTEMP_off(val = SvREFCNT_inc_NN(*++MARK));
579 2 100         else if (ckWARN(WARN_MISC))
580 1           Perl_warner(aTHX_ packWARN(WARN_MISC),
581             "Odd number of elements in anonymous hash");
582 31 100         if (val == &PL_sv_undef)
583 3           (void) hv_delete_ent(hv, key, G_DISCARD, 0);
584             else
585 28           (void) hv_store_ent(hv, key, val, 0);
586             }
587 21           SP = ORIGMARK;
588 21 100         if (PL_op->op_flags & OPf_SPECIAL) {
589 17           sv = da_refgen(aTHX_ (SV *) hv);
590 17           SvREFCNT_dec((SV *) hv);
591             } else {
592 4           sv = sv_2mortal((SV *) hv);
593             }
594 21 50         XPUSHs(sv);
595 21           RETURN;
596             }
597              
598 15           STATIC OP *DataAlias_pp_aelemfast(pTHX) {
599 15           dSP;
600 15           AV *av =
601             #if (PERL_COMBI_VERSION >= 5015000)
602 15           PL_op->op_type == OP_AELEMFAST_LEX ?
603             #else
604             (PL_op->op_flags & OPf_SPECIAL) ?
605             #endif
606 15 100         (AV *) PAD_SV(PL_op->op_targ) : GvAVn(cGVOP_gv);
    50          
607 15           IV index = PL_op->op_private;
608 15 50         if (!av_fetch(av, index, TRUE))
609 0           DIE(aTHX_ PL_no_aelem, index);
610 15 50         XPUSHaa(av, index);
611 15           RETURN;
612             }
613              
614 6           STATIC bool da_badmagic(pTHX_ SV *sv) {
615 6           MAGIC *mg = SvMAGIC(sv);
616 12 100         while (mg) {
617 6 50         if (isUPPER(mg->mg_type))
618 0           return TRUE;
619 6           mg = mg->mg_moremagic;
620             }
621 6           return FALSE;
622             }
623              
624 4           STATIC OP *DataAlias_pp_aelem(pTHX) {
625 4           dSP;
626 4           SV *elem = POPs, **svp;
627 4           AV *av = (AV *) POPs;
628 4 50         IV index = SvIV(elem);
629 4 50         if (SvRMAGICAL(av) && da_badmagic(aTHX_ (SV *) av))
    0          
630 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "array");
631 4 50         if (SvROK(elem) && !SvGAMAGIC(elem) && ckWARN(WARN_MISC))
    0          
    0          
    0          
    0          
    0          
632 0           Perl_warner(aTHX_ packWARN(WARN_MISC),
633             "Use of reference \"%"SVf"\" as array index", elem);
634 4 50         if (SvTYPE(av) != SVt_PVAV)
635 0           RETPUSHUNDEF;
636 4 50         if (index > DA_ARRAY_MAXIDX || !(svp = av_fetch(av, index, TRUE)))
    50          
637 0           DIE(aTHX_ PL_no_aelem, index);
638 4 100         if (PL_op->op_private & OPpLVAL_INTRO)
639 2           save_aelem(av, index, svp);
640 4           PUSHaa(av, index);
641 4           RETURN;
642             }
643              
644             #if DA_FEATURE_AVHV
645             STATIC I32 da_avhv_index(pTHX_ AV *av, SV *key) {
646             HV *keys = (HV *) SvRV(*AvARRAY(av));
647             HE *he = hv_fetch_ent(keys, key, FALSE, 0);
648             I32 index;
649             if (!he)
650             Perl_croak(aTHX_ "No such pseudo-hash field \"%s\"",
651             SvPV_nolen(key));
652             if ((index = SvIV(HeVAL(he))) <= 0)
653             Perl_croak(aTHX_ "Bad index while coercing array into hash");
654             if (index > AvMAX(av)) {
655             I32 real = AvREAL(av);
656             AvREAL_on(av);
657             av_extend(av, index);
658             if (!real)
659             AvREAL_off(av);
660             }
661             return index;
662             }
663             #endif
664              
665             #ifndef save_hdelete
666             STATIC void DataAlias_save_hdelete(pTHX_ HV *hv, SV *keysv) {
667             STRLEN len;
668             const char *key = SvPV_const(keysv, len);
669             save_delete(hv, savepvn(key, len), SvUTF8(keysv) ? -(I32)len : (I32)len);
670             }
671             #define save_hdelete(hv, keysv) DataAlias_save_hdelete(aTHX_ (hv), (keysv))
672             #endif
673              
674 11           STATIC OP *DataAlias_pp_helem(pTHX) {
675 11           dSP;
676 11           SV *key = POPs;
677 11           HV *hv = (HV *) POPs;
678             HE *he;
679 11           bool const localizing = PL_op->op_private & OPpLVAL_INTRO;
680              
681 11 50         if (SvRMAGICAL(hv) && da_badmagic(aTHX_ (SV *) hv))
    0          
682 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "hash");
683              
684 11 50         if (SvTYPE(hv) == SVt_PVHV) {
685 11           bool existed = TRUE;
686 11 100         if (localizing)
687 2           existed = hv_exists_ent(hv, key, 0);
688 11 50         if (!(he = hv_fetch_ent(hv, key, TRUE, 0)))
689 0 0         DIE(aTHX_ PL_no_helem, SvPV_nolen(key));
690 11 100         if (localizing) {
691 2 100         if (!existed)
692 1           save_hdelete(hv, key);
693             else
694 11           save_helem(hv, key, &HeVAL(he));
695             }
696             }
697             #if DA_FEATURE_AVHV
698             else if (SvTYPE(hv) == SVt_PVAV && avhv_keys((AV *) hv)) {
699             I32 i = da_avhv_index(aTHX_ (AV *) hv, key);
700             if (localizing)
701             save_aelem((AV *) hv, i, &AvARRAY(hv)[i]);
702             key = (SV *) (Size_t) i;
703             }
704             #endif
705             else {
706 0           hv = (HV *) &PL_sv_undef;
707 0           key = NULL;
708             }
709 11           PUSHaa(hv, key);
710 11           RETURN;
711             }
712              
713 3           STATIC OP *DataAlias_pp_aslice(pTHX) {
714 3           dSP; dMARK;
715 3           AV *av = (AV *) POPs;
716             IV max, count;
717             SV **src, **dst;
718 3           const U32 local = PL_op->op_private & OPpLVAL_INTRO;
719 3 50         if (SvTYPE(av) != SVt_PVAV)
720 0           DIE(aTHX_ "Not an array");
721 3 50         if (SvRMAGICAL(av) && da_badmagic(aTHX_ (SV *) av))
    0          
722 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "array");
723 3           count = SP - MARK;
724 3 50         EXTEND(sp, count);
    50          
725 3           src = SP;
726 3           dst = SP += count;
727 3           max = AvFILLp(av);
728 3           count = max + 1;
729 9 100         while (MARK < src) {
730 6 50         IV i = SvIVx(*src);
731 6 50         if (i > DA_ARRAY_MAXIDX || (i < 0 && (i += count) < 0))
    50          
    0          
732 0           DIE(aTHX_ PL_no_aelem, SvIVX(*src));
733 6 100         if (local)
734 2           save_aelem(av, i, av_fetch(av, i, TRUE));
735 6 100         if (i > max)
736 2           max = i;
737 6           *dst-- = (SV *) (Size_t) i;
738 6           *dst-- = (SV *) av;
739 6           --src;
740             }
741 3 100         if (max > AvMAX(av))
742 1           av_extend(av, max);
743 3           RETURN;
744             }
745              
746 3           STATIC OP *DataAlias_pp_hslice(pTHX) {
747 3           dSP; dMARK;
748 3           HV *hv = (HV *) POPs;
749             SV *key;
750             HE *he;
751             SV **src, **dst;
752 3           IV i = SP - MARK;
753 3 50         if (SvRMAGICAL(hv) && da_badmagic(aTHX_ (SV *) hv))
    0          
754 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "hash");
755 3 50         EXTEND(sp, i);
    50          
756 3           src = SP;
757 3           dst = SP += i;
758 3 50         if (SvTYPE(hv) == SVt_PVHV) {
759 9 100         while (MARK < src) {
760 6 50         if (!(he = hv_fetch_ent(hv, key = *src--, TRUE, 0)))
761 0 0         DIE(aTHX_ PL_no_helem, SvPV_nolen(key));
762 6 100         if (PL_op->op_private & OPpLVAL_INTRO)
763 2           save_helem(hv, key, &HeVAL(he));
764 6           *dst-- = key;
765 6           *dst-- = (SV *) hv;
766             }
767             }
768             #if DA_FEATURE_AVHV
769             else if (SvTYPE(hv) == SVt_PVAV && avhv_keys((AV *) hv)) {
770             while (MARK < src) {
771             i = da_avhv_index(aTHX_ (AV *) hv, key = *src--);
772             if (PL_op->op_private & OPpLVAL_INTRO)
773             save_aelem((AV *) hv, i, &AvARRAY(hv)[i]);
774             *dst-- = (SV *) (Size_t) i;
775             *dst-- = (SV *) hv;
776             }
777             }
778             #endif
779             else {
780 0           DIE(aTHX_ "Not a hash");
781             }
782 3           RETURN;
783             }
784              
785             #if DA_HAVE_OP_PADRANGE
786              
787 7           STATIC OP *DataAlias_pp_padrange_generic(pTHX_ bool is_single) {
788 7           dSP;
789 7           IV start = PL_op->op_targ;
790 7           IV count = PL_op->op_private & OPpPADRANGE_COUNTMASK;
791             IV index;
792 7 100         if (PL_op->op_flags & OPf_SPECIAL) {
793 5 50         AV *av = GvAVn(PL_defgv);
794 5 50         PUSHMARK(SP);
795 5 100         if (is_single) {
796 1 50         XPUSHs((SV*)av);
797             } else {
798 4 50         const I32 maxarg = AvFILL(av) + 1;
799 4 50         EXTEND(SP, maxarg);
    50          
800 4 50         if (SvRMAGICAL(av)) {
801             U32 i;
802 0 0         for (i=0; i < (U32)maxarg; i++) {
803 0           SV ** const svp =
804 0           av_fetch(av, i, FALSE);
805 0           SP[i+1] = svp ?
806 0           SvGMAGICAL(*svp) ?
807 0 0         (mg_get(*svp), *svp) :
808 0 0         *svp :
809             &PL_sv_undef;
810             }
811             } else {
812 4 50         Copy(AvARRAY(av), SP+1, maxarg, SV*);
813             }
814 4           SP += maxarg;
815             }
816             }
817 7 50         if ((PL_op->op_flags & OPf_WANT) != OPf_WANT_VOID) {
818 7 50         PUSHMARK(SP);
819 7 50         EXTEND(SP, count << 1);
    50          
820             }
821 17 100         for(index = start; index != start+count; index++) {
822             Size_t da_type;
823 10 100         if (is_single) {
824 1           da_type = DA_ALIAS_PAD;
825             } else {
826 9           switch(SvTYPE(PAD_SVl(index))) {
827 3           case SVt_PVAV: da_type = DA_ALIAS_AV; break;
828 0           case SVt_PVHV: da_type = DA_ALIAS_HV; break;
829 6           default: da_type = DA_ALIAS_PAD; break;
830             }
831             }
832 10 50         if (PL_op->op_private & OPpLVAL_INTRO) {
833 10 100         if (da_type == DA_ALIAS_PAD) {
834 7           SAVEGENERICSV(PAD_SVl(index));
835 7           PAD_SVl(index) = &PL_sv_undef;
836             } else {
837 3           SAVECLEARSV(PAD_SVl(index));
838             }
839             }
840 10 50         if ((PL_op->op_flags & OPf_WANT) != OPf_WANT_VOID)
841 10 100         PUSHaa(da_type, da_type == DA_ALIAS_PAD ?
842             (Size_t)index :
843             (Size_t)PAD_SVl(index));
844             }
845 7           RETURN;
846             }
847              
848 6           STATIC OP *DataAlias_pp_padrange_list(pTHX) {
849 6           return DataAlias_pp_padrange_generic(aTHX_ 0);
850             }
851              
852 1           STATIC OP *DataAlias_pp_padrange_single(pTHX) {
853 1           return DataAlias_pp_padrange_generic(aTHX_ 1);
854             }
855              
856             #endif
857              
858 31           STATIC OP *DataAlias_pp_padsv(pTHX) {
859 31           dSP;
860 31           IV index = PL_op->op_targ;
861 31 100         if (PL_op->op_private & OPpLVAL_INTRO) {
862 9           SAVEGENERICSV(PAD_SVl(index));
863 9           PAD_SVl(index) = &PL_sv_undef;
864             }
865 31 50         XPUSHaa(DA_ALIAS_PAD, index);
866 31           RETURN;
867             }
868              
869 1           STATIC OP *DataAlias_pp_padav(pTHX) {
870 1           dSP; dTARGET;
871 1 50         if (PL_op->op_private & OPpLVAL_INTRO)
872 1           SAVECLEARSV(PAD_SVl(PL_op->op_targ));
873 1 50         XPUSHaa(DA_ALIAS_AV, TARG);
874 1           RETURN;
875             }
876              
877 0           STATIC OP *DataAlias_pp_padhv(pTHX) {
878 0           dSP; dTARGET;
879 0 0         if (PL_op->op_private & OPpLVAL_INTRO)
880 0           SAVECLEARSV(PAD_SVl(PL_op->op_targ));
881 0 0         XPUSHaa(DA_ALIAS_HV, TARG);
882 0           RETURN;
883             }
884              
885 62           STATIC OP *DataAlias_pp_gvsv(pTHX) {
886 62           dSP;
887 62           GV *gv = cGVOP_gv;
888 62 100         if (PL_op->op_private & OPpLVAL_INTRO) {
889 4           da_localize_gvar(aTHX_ GvGP(gv), &GvSV(gv));
890 4           GvSV(gv) = newSV(0);
891             }
892 62 50         XPUSHaa(DA_ALIAS_RV, gv);
893 62           RETURN;
894             }
895              
896 1           STATIC OP *DataAlias_pp_gvsv_r(pTHX) {
897 1           dSP;
898 1           GV *gv = cGVOP_gv;
899 1 50         if (PL_op->op_private & OPpLVAL_INTRO) {
900 1           da_localize_gvar(aTHX_ GvGP(gv), &GvSV(gv));
901 1           GvSV(gv) = newSV(0);
902             }
903 1 50         XPUSHs(GvSV(gv));
904 1           RETURN;
905             }
906              
907 10           STATIC GV *fixglob(pTHX_ GV *gv) {
908 10           SV **svp = hv_fetch(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), FALSE);
909             GV *egv;
910 10 50         if (!svp || !(egv = (GV *) *svp) || GvGP(egv) != GvGP(gv))
    50          
    50          
911 0           return gv;
912 10           GvEGV(gv) = egv;
913 10           return egv;
914             }
915              
916 39           STATIC OP *DataAlias_pp_rv2sv(pTHX) {
917 39           dSP; dPOPss;
918 39 100         if (!SvROK(sv) && SvTYPE(sv) != SVt_PVGV) do {
    100          
919             const char *tname;
920             U32 type;
921 2           switch (PL_op->op_type) {
922 0           case OP_RV2AV: type = SVt_PVAV; tname = "an ARRAY"; break;
923 0           case OP_RV2HV: type = SVt_PVHV; tname = "a HASH"; break;
924 2           default: type = SVt_PV; tname = "a SCALAR";
925             }
926 2 50         if (SvGMAGICAL(sv)) {
927 0           mg_get(sv);
928 0 0         if (SvROK(sv))
929 0           break;
930             }
931 2 50         if (!SvOK(sv))
    0          
    0          
932 0           break;
933 2 100         if (PL_op->op_private & HINT_STRICT_REFS)
934 1 50         DIE(aTHX_ msg_no_symref, SvPV_nolen(sv), tname);
935 1 50         sv = (SV *) gv_fetchpv(SvPV_nolen(sv), TRUE, type);
936             } while (0);
937 38 100         if (SvTYPE(sv) == SVt_PVGV)
938 28 100         sv = (SV *) (GvEGV(sv) ? GvEGV(sv) : fixglob(aTHX_ (GV *) sv));
939 38 100         if (PL_op->op_private & OPpLVAL_INTRO) {
940 12 100         if (SvTYPE(sv) != SVt_PVGV || SvFAKE(sv))
    50          
941 3           DIE(aTHX_ "%s", PL_no_localize_ref);
942 9           switch (PL_op->op_type) {
943             case OP_RV2AV:
944 4           da_localize_gvar(aTHX_ GvGP(sv), (SV **) &GvAV(sv));
945 4           break;
946             case OP_RV2HV:
947 4           da_localize_gvar(aTHX_ GvGP(sv), (SV **) &GvHV(sv));
948 4           break;
949             default:
950 1           da_localize_gvar(aTHX_ GvGP(sv), &GvSV(sv));
951 1           GvSV(sv) = newSV(0);
952             }
953             }
954 35 50         XPUSHaa(DA_ALIAS_RV, sv);
955 35           RETURN;
956             }
957              
958 2           STATIC OP *DataAlias_pp_rv2sv_r(pTHX) {
959             U8 savedflags;
960 2           OP *op = PL_op, *ret;
961              
962 2           DataAlias_pp_rv2sv(aTHX);
963 2           PL_stack_sp[-1] = PL_stack_sp[0];
964 2           --PL_stack_sp;
965              
966 2           savedflags = op->op_private;
967 2           op->op_private = savedflags & ~OPpLVAL_INTRO;
968              
969 2           ret = PL_ppaddr[op->op_type](aTHX);
970              
971 2           op->op_private = savedflags;
972              
973 2           return ret;
974             }
975              
976 15           STATIC OP *DataAlias_pp_rv2gv(pTHX) {
977 15           dSP; dPOPss;
978 15 100         if (SvROK(sv)) {
979 2           wasref: sv = SvRV(sv);
980 2 50         if (SvTYPE(sv) != SVt_PVGV)
981 0           DIE(aTHX_ "Not a GLOB reference");
982 13 100         } else if (SvTYPE(sv) != SVt_PVGV) {
983 2 50         if (SvGMAGICAL(sv)) {
984 0           mg_get(sv);
985 0 0         if (SvROK(sv))
986 0           goto wasref;
987             }
988 2 50         if (!SvOK(sv))
    0          
    0          
989 0           DIE(aTHX_ PL_no_usym, "a symbol");
990 2 100         if (PL_op->op_private & HINT_STRICT_REFS)
991 1 50         DIE(aTHX_ msg_no_symref, SvPV_nolen(sv), "a symbol");
992 1 50         sv = (SV *) gv_fetchpv(SvPV_nolen(sv), TRUE, SVt_PVGV);
993             }
994 14 50         if (SvTYPE(sv) == SVt_PVGV)
995 14 100         sv = (SV *) (GvEGV(sv) ? GvEGV(sv) : fixglob(aTHX_ (GV *) sv));
996 14 100         if (PL_op->op_private & OPpLVAL_INTRO)
997 11           save_gp((GV *) sv, !(PL_op->op_flags & OPf_SPECIAL));
998 14 50         XPUSHaa(DA_ALIAS_GV, sv);
999 14           RETURN;
1000             }
1001              
1002 5           STATIC OP *DataAlias_pp_rv2av(pTHX) {
1003 5           OP *ret = PL_ppaddr[OP_RV2AV](aTHX);
1004 5           dSP;
1005 5           SV *av = POPs;
1006 5 50         XPUSHaa(DA_ALIAS_AV, av);
1007 5           PUTBACK;
1008 5           return ret;
1009             }
1010              
1011 10           STATIC OP *DataAlias_pp_rv2hv(pTHX) {
1012 10           OP *ret = PL_ppaddr[OP_RV2HV](aTHX);
1013 10           dSP;
1014 10           SV *hv = POPs;
1015 10 50         XPUSHaa(DA_ALIAS_HV, hv);
1016 10           PUTBACK;
1017 10           return ret;
1018             }
1019              
1020 76           STATIC OP *DataAlias_pp_sassign(pTHX) {
1021 76           dSP;
1022             SV *a1, *a2, *value;
1023 76 100         if (PL_op->op_private & OPpASSIGN_BACKWARDS) {
1024 17           value = POPs, a2 = POPs, a1 = TOPs;
1025 17           SETs(value);
1026             } else {
1027 59           a2 = POPs, a1 = POPs, value = TOPs;
1028             }
1029 76           da_alias(aTHX_ a1, a2, value);
1030 76           RETURN;
1031             }
1032              
1033 72           STATIC OP *DataAlias_pp_aassign(pTHX) {
1034 72           dSP;
1035             SV **left, **llast, **right, **rlast;
1036 72 100         I32 gimme = GIMME_V;
1037 72           I32 done = FALSE;
1038 72 50         EXTEND(sp, 1);
1039 72           left = POPMARK + PL_stack_base + 1;
1040 72           llast = SP;
1041 72           right = POPMARK + PL_stack_base + 1;
1042 72           rlast = left - 1;
1043 72 100         if (PL_op->op_private & OPpALIAS) {
1044 29           U32 hash = (PL_op->op_private & OPpALIASHV);
1045 29 100         U32 type = hash ? SVt_PVHV : SVt_PVAV;
1046 29           SV *a2 = POPs;
1047 29           SV *a1 = POPs;
1048             OPCODE savedop;
1049 29 50         if (SP != rlast)
1050 0           DIE(aTHX_ "Panic: unexpected number of lvalues");
1051 29           PUTBACK;
1052 29 100         if (right != rlast || SvTYPE(*right) != type) {
    100          
1053 8 50         PUSHMARK(right - 1);
1054 8 100         hash ? DataAlias_pp_anonhash(aTHX) : DataAlias_pp_anonlist(aTHX);
1055 8           SPAGAIN;
1056             }
1057 29           da_alias(aTHX_ a1, a2, TOPs);
1058 29           savedop = PL_op->op_type;
1059 29 100         PL_op->op_type = hash ? OP_RV2HV : OP_RV2AV;
1060 29           PL_ppaddr[PL_op->op_type](aTHX);
1061 29           PL_op->op_type = savedop;
1062 29           return NORMAL;
1063             }
1064 43           SP = right - 1;
1065 159 100         while (SP < rlast)
1066 116 100         if (!SvTEMP(*++SP))
1067 105           sv_2mortal(SvREFCNT_inc_NN(*SP));
1068 43           SP = right - 1;
1069 132 100         while (left <= llast) {
1070 90           SV *a1 = *left++, *a2;
1071 90 100         if (a1 == &PL_sv_undef) {
1072 3           right++;
1073 3           continue;
1074             }
1075 87           a2 = *left++;
1076 87           switch ((Size_t) a1) {
1077             case DA_ALIAS_AV: {
1078             SV **svp;
1079 9 50         if (SvRMAGICAL(a2) && da_badmagic(aTHX_ a2))
    0          
1080 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "array");
1081 9           av_clear((AV *) a2);
1082 9 50         if (done || right > rlast)
    100          
1083             break;
1084 7           av_extend((AV *) a2, rlast - right);
1085 7           AvFILLp((AV *) a2) = rlast - right;
1086 7           svp = AvARRAY((AV *) a2);
1087 27 100         while (right <= rlast)
1088 20           SvTEMP_off(*svp++ = SvREFCNT_inc_NN(*right++));
1089 7           break;
1090             } case DA_ALIAS_HV: {
1091 10           SV *tmp, *val, **svp = rlast;
1092 10           U32 dups = 0, nils = 0;
1093             HE *he;
1094             #if DA_FEATURE_AVHV
1095             if (SvTYPE(a2) == SVt_PVAV)
1096             goto phash;
1097             #endif
1098 10 100         if (SvRMAGICAL(a2) && da_badmagic(aTHX_ a2))
    50          
1099 0           DIE(aTHX_ DA_TIED_ERR, "put", "into", "hash");
1100 10           hv_clear((HV *) a2);
1101 10 50         if (done || right > rlast)
    100          
1102             break;
1103 8           done = TRUE;
1104 8           hv_ksplit((HV *) a2, (rlast - right + 2) >> 1);
1105 8 100         if (1 & ~(rlast - right)) {
    100          
1106 3 100         if (ckWARN(WARN_MISC))
1107 1           Perl_warner(aTHX_ packWARN(WARN_MISC),
1108             DA_ODD_HASH_ERR);
1109 2           *++svp = &PL_sv_undef;
1110             }
1111 27 100         while (svp > right) {
1112 20           val = *svp--; tmp = *svp--;
1113 20           he = hv_fetch_ent((HV *) a2, tmp, TRUE, 0);
1114 20 50         if (!he) /* is this possible? */
1115 0 0         DIE(aTHX_ PL_no_helem, SvPV_nolen(tmp));
1116 20           tmp = HeVAL(he);
1117 20 100         if (SvREFCNT(tmp) > 1) { /* existing element */
1118 6           svp[1] = svp[2] = NULL;
1119 6           dups += 2;
1120 6           continue;
1121             }
1122 14 100         if (val == &PL_sv_undef)
1123 5           nils++;
1124 14           SvREFCNT_dec(tmp);
1125 14           SvTEMP_off(HeVAL(he) =
1126             SvREFCNT_inc_simple_NN(val));
1127             }
1128 17 100         while (nils && (he = hv_iternext((HV *) a2))) {
    50          
1129 10 100         if (HeVAL(he) == &PL_sv_undef) {
1130 5           HeVAL(he) = &PL_sv_placeholder;
1131 5           HvPLACEHOLDERS(a2)++;
1132 5           nils--;
1133             }
1134             }
1135 7 100         if (gimme != G_LIST || !dups) {
    100          
1136 5           right = rlast - dups + 1;
1137 5           break;
1138             }
1139 15 100         while (svp++ < rlast) {
1140 13 100         if (*svp)
1141 7           *right++ = *svp;
1142             }
1143 2           break;
1144             }
1145             #if DA_FEATURE_AVHV
1146             phash: {
1147             SV *key, *val, **svp = rlast, **he;
1148             U32 dups = 0;
1149             I32 i;
1150             if (SvRMAGICAL(a2) && da_badmagic(aTHX_ a2))
1151             DIE(aTHX_ DA_TIED_ERR, "put", "into", "hash");
1152             avhv_keys((AV *) a2);
1153             av_fill((AV *) a2, 0);
1154             if (done || right > rlast)
1155             break;
1156             done = TRUE;
1157             if (1 & ~(rlast - right)) {
1158             if (ckWARN(WARN_MISC))
1159             Perl_warner(aTHX_ packWARN(WARN_MISC),
1160             DA_ODD_HASH_ERR);
1161             *++svp = &PL_sv_undef;
1162             }
1163             ENTER;
1164             while (svp > right) {
1165             val = *svp--; key = *svp--;
1166             i = da_avhv_index(aTHX_ (AV *) a2, key);
1167             he = &AvARRAY(a2)[i];
1168             if (*he != &PL_sv_undef) {
1169             svp[1] = svp[2] = NULL;
1170             dups += 2;
1171             continue;
1172             }
1173             SvREFCNT_dec(*he);
1174             if (val == &PL_sv_undef) {
1175             SAVESPTR(*he);
1176             *he = NULL;
1177             } else {
1178             if (i > AvFILLp(a2))
1179             AvFILLp(a2) = i;
1180             SvTEMP_off(*he =
1181             SvREFCNT_inc_simple_NN(val));
1182             }
1183             }
1184             LEAVE;
1185             if (gimme != G_LIST || !dups) {
1186             right = rlast - dups + 1;
1187             break;
1188             }
1189             while (svp++ < rlast) {
1190             if (*svp)
1191             *right++ = *svp;
1192             }
1193             break;
1194             }
1195             #endif
1196             default:
1197 68 100         if (right > rlast)
1198 14           da_alias(aTHX_ a1, a2, &PL_sv_undef);
1199 54 100         else if (done)
1200 4           da_alias(aTHX_ a1, a2, *right = &PL_sv_undef);
1201             else
1202 50           da_alias(aTHX_ a1, a2, *right);
1203 68           right++;
1204 68           break;
1205             }
1206             }
1207 42 100         if (gimme == G_LIST) {
1208 12           SP = right - 1;
1209 12 50         EXTEND(SP, 0);
1210 19 100         while (rlast < SP)
1211 7           *++rlast = &PL_sv_undef;
1212 12           RETURN;
1213 30 100         } else if (gimme == G_SCALAR) {
1214 12           dTARGET;
1215 12 50         XPUSHi(rlast - SP);
    50          
1216             }
1217 30           RETURN;
1218             }
1219              
1220 14           STATIC OP *DataAlias_pp_andassign(pTHX) {
1221 14           dSP;
1222 14           SV *a2 = POPs;
1223 14           SV *sv = da_fetch(aTHX_ TOPs, a2);
1224 14 50         if (SvTRUE(sv)) {
    50          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    100          
1225             /* no PUTBACK */
1226 6           return cLOGOP->op_other;
1227             }
1228 8           SETs(sv);
1229 8           RETURN;
1230             }
1231              
1232 14           STATIC OP *DataAlias_pp_orassign(pTHX) {
1233 14           dSP;
1234 14           SV *a2 = POPs;
1235 14           SV *sv = da_fetch(aTHX_ TOPs, a2);
1236 14 50         if (!SvTRUE(sv)) {
    50          
    0          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
1237             /* no PUTBACK */
1238 8           return cLOGOP->op_other;
1239             }
1240 6           SETs(sv);
1241 6           RETURN;
1242             }
1243              
1244             #if DA_HAVE_OP_DORASSIGN
1245 5           STATIC OP *DataAlias_pp_dorassign(pTHX) {
1246 5           dSP;
1247 5           SV *a2 = POPs;
1248 5           SV *sv = da_fetch(aTHX_ TOPs, a2);
1249 5 100         if (!SvOK(sv)) {
    50          
    50          
1250             /* no PUTBACK */
1251 3           return cLOGOP->op_other;
1252             }
1253 2           SETs(sv);
1254 2           RETURN;
1255             }
1256             #endif
1257              
1258 5           STATIC OP *DataAlias_pp_push(pTHX) {
1259 5           dSP; dMARK; dORIGMARK; dTARGET;
1260 5           AV *av = (AV *) *++MARK;
1261             I32 i;
1262 5 100         if (SvRMAGICAL(av) && da_badmagic(aTHX_ (SV *) av))
    50          
1263 0           DIE(aTHX_ DA_TIED_ERR, "push", "onto", "array");
1264 5 100         i = AvFILL(av);
1265 5           av_extend(av, i + (SP - MARK));
1266 12 100         while (MARK < SP)
1267 7           av_store(av, ++i, SvREFCNT_inc_NN(*++MARK));
1268 5           SP = ORIGMARK;
1269 5 50         PUSHi(i + 1);
1270 5           RETURN;
1271             }
1272              
1273 4           STATIC OP *DataAlias_pp_unshift(pTHX) {
1274 4           dSP; dMARK; dORIGMARK; dTARGET;
1275 4           AV *av = (AV *) *++MARK;
1276 4           I32 i = 0;
1277 4 50         if (SvRMAGICAL(av) && da_badmagic(aTHX_ (SV *) av))
    0          
1278 0           DIE(aTHX_ DA_TIED_ERR, "unshift", "onto", "array");
1279 4           av_unshift(av, SP - MARK);
1280 10 100         while (MARK < SP)
1281 6           av_store(av, i++, SvREFCNT_inc_NN(*++MARK));
1282 4           SP = ORIGMARK;
1283 4 50         PUSHi(AvFILL(av) + 1);
    50          
1284 4           RETURN;
1285             }
1286              
1287 15           STATIC OP *DataAlias_pp_splice(pTHX) {
1288 15           dSP; dMARK; dORIGMARK;
1289 15           I32 ins = SP - MARK - 3;
1290 15           AV *av = (AV *) MARK[1];
1291             I32 off, del, count, i;
1292             SV **svp, *tmp;
1293 15 50         if (ins < 0) /* ?! */
1294 0           DIE(aTHX_ "Too few arguments for DataAlias_pp_splice");
1295 15 50         if (SvRMAGICAL(av) && da_badmagic(aTHX_ (SV *) av))
    0          
1296 0           DIE(aTHX_ DA_TIED_ERR, "splice", "onto", "array");
1297 15           count = AvFILLp(av) + 1;
1298 15 50         off = SvIV(MARK[2]);
1299 15 100         if (off < 0 && (off += count) < 0)
    50          
1300 0           DIE(aTHX_ PL_no_aelem, off - count);
1301 15 50         del = SvIV(ORIGMARK[3]);
1302 15 100         if (del < 0 && (del += count - off) < 0)
    100          
1303 1           del = 0;
1304 15 100         if (off > count) {
1305 2 100         if (ckWARN(WARN_MISC))
1306 1           Perl_warner(aTHX_ packWARN(WARN_MISC),
1307             "splice() offset past end of array");
1308 1           off = count;
1309             }
1310 14 100         if ((count -= off + del) < 0) /* count of trailing elems */
1311 1           del += count, count = 0;
1312 14           i = off + ins + count - 1;
1313 14 100         if (i > AvMAX(av))
1314 4           av_extend(av, i);
1315 14 50         if (!AvREAL(av) && AvREIFY(av))
    0          
1316 0           av_reify(av);
1317 14           AvFILLp(av) = i;
1318 14           MARK = ORIGMARK + 4;
1319 14           svp = AvARRAY(av) + off;
1320 35 100         for (i = 0; i < ins; i++)
1321 21           SvTEMP_off(SvREFCNT_inc_NN(MARK[i]));
1322 14 100         if (ins > del) {
1323 7 50         Move(svp+del, svp+ins, INT2SIZE(count), SV *);
1324 9 100         for (i = 0; i < del; i++)
1325 2           tmp = MARK[i], MARK[i-3] = svp[i], svp[i] = tmp;
1326 7 50         Copy(MARK+del, svp+del, INT2SIZE(ins-del), SV *);
1327             } else {
1328 16 100         for (i = 0; i < ins; i++)
1329 9           tmp = MARK[i], MARK[i-3] = svp[i], svp[i] = tmp;
1330 7 100         if (ins != del)
1331 3 50         Copy(svp+ins, MARK-3+ins, INT2SIZE(del-ins), SV *);
1332 7 50         Move(svp+del, svp+ins, INT2SIZE(count), SV *);
1333             }
1334 14           MARK -= 3;
1335 28 100         for (i = 0; i < del; i++)
1336 14           sv_2mortal(MARK[i]);
1337 14           SP = MARK + del - 1;
1338 14           RETURN;
1339             }
1340              
1341 57           STATIC OP *DataAlias_pp_leave(pTHX) {
1342 57           dSP;
1343             SV **newsp;
1344             #ifdef POPBLOCK
1345             PMOP *newpm;
1346             #endif
1347             I32 gimme;
1348             PERL_CONTEXT *cx;
1349             SV *sv;
1350              
1351 57 100         if (PL_op->op_flags & OPf_SPECIAL)
1352 2           cxstack[cxstack_ix].blk_oldpm = PL_curpm;
1353              
1354             #ifdef POPBLOCK
1355             POPBLOCK(cx, newpm);
1356             gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
1357             #else
1358 57           cx = CX_CUR();
1359             assert(CxTYPE(cx) == CXt_BLOCK);
1360 57           gimme = cx->blk_gimme;
1361 57           newsp = PL_stack_base + cx->blk_oldsp;
1362             #endif
1363              
1364 57 100         if (gimme == G_SCALAR) {
1365 18 50         if (newsp == SP) {
1366 0           *++newsp = &PL_sv_undef;
1367             } else {
1368 18           sv = SvREFCNT_inc_NN(TOPs);
1369 18 100         FREETMPS;
1370 18           *++newsp = sv_2mortal(sv);
1371             }
1372 39 100         } else if (gimme == G_LIST) {
1373 45 100         while (newsp < SP)
1374 27 100         if (!SvTEMP(sv = *++newsp))
1375 19           sv_2mortal(SvREFCNT_inc_simple_NN(sv));
1376             }
1377 57           PL_stack_sp = newsp;
1378             #ifdef POPBLOCK
1379             PL_curpm = newpm;
1380             LEAVE;
1381             #else
1382 57 100         CX_LEAVE_SCOPE(cx);
1383 57           cx_popblock(cx);
1384 57           CX_POP(cx);
1385             #endif
1386 57           return NORMAL;
1387             }
1388              
1389 37           STATIC OP *DataAlias_pp_return(pTHX) {
1390 37           dSP; dMARK;
1391             I32 cxix;
1392             PERL_CONTEXT *cx;
1393 37           bool clearerr = FALSE;
1394             I32 gimme;
1395             SV **newsp;
1396             #ifdef POPBLOCK
1397             PMOP *newpm;
1398             #endif
1399 37           I32 optype = 0, type = 0;
1400 37 100         SV *sv = (MARK < SP) ? TOPs : &PL_sv_undef;
1401             OP *retop;
1402              
1403 37           cxix = cxstack_ix;
1404 38 50         while (cxix >= 0) {
1405 38           cx = &cxstack[cxix];
1406 38           type = CxTYPE(cx);
1407 38 100         if (type == CXt_EVAL || type == CXt_SUB || type == CXt_FORMAT)
    100          
    50          
1408             break;
1409 1           cxix--;
1410             }
1411              
1412             #if DA_FEATURE_MULTICALL
1413 37 50         if (cxix < 0) {
1414 0 0         if (CxMULTICALL(cxstack)) { /* sort block */
1415 0           dounwind(0);
1416 0           *(PL_stack_sp = PL_stack_base + 1) = sv;
1417 0           return 0;
1418             }
1419 0           DIE(aTHX_ "Can't return outside a subroutine");
1420             }
1421             #else
1422             if (PL_curstackinfo->si_type == PERLSI_SORT && cxix <= PL_sortcxix) {
1423             if (cxstack_ix > PL_sortcxix)
1424             dounwind(PL_sortcxix);
1425             *(PL_stack_sp = PL_stack_base + 1) = sv;
1426             return 0;
1427             }
1428             if (cxix < 0)
1429             DIE(aTHX_ "Can't return outside a subroutine");
1430             #endif
1431              
1432              
1433 37 100         if (cxix < cxstack_ix)
1434 1           dounwind(cxix);
1435              
1436             #if DA_FEATURE_MULTICALL
1437 37 50         if (CxMULTICALL(&cxstack[cxix])) {
1438 0           gimme = cxstack[cxix].blk_gimme;
1439 0 0         if (gimme == G_VOID)
1440 0           PL_stack_sp = PL_stack_base;
1441 0 0         else if (gimme == G_SCALAR)
1442 0           *(PL_stack_sp = PL_stack_base + 1) = sv;
1443 0           return 0;
1444             }
1445             #endif
1446              
1447             #ifdef POPBLOCK
1448             POPBLOCK(cx, newpm);
1449             #else
1450 37           cx = CX_CUR();
1451 37           gimme = cx->blk_gimme;
1452 37           newsp = PL_stack_base + cx->blk_oldsp;
1453             #endif
1454 37           switch (type) {
1455             case CXt_SUB:
1456             #if DA_FEATURE_RETOP
1457 25           retop = cx->blk_sub.retop;
1458             #endif
1459             #ifdef POPBLOCK
1460             cxstack_ix++; /* temporarily protect top context */
1461             #endif
1462 25           break;
1463             case CXt_EVAL:
1464 12           clearerr = !(PL_in_eval & EVAL_KEEPERR);
1465             #ifdef POPBLOCK
1466             POPEVAL(cx);
1467             #else
1468 12           cx_popeval(cx);
1469             #endif
1470             #if DA_FEATURE_RETOP
1471 12           retop = cx->blk_eval.retop;
1472             #endif
1473 12 100         if (CxTRYBLOCK(cx))
1474 5           break;
1475             lex_end();
1476 7 50         if (optype == OP_REQUIRE && !SvTRUE(sv)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1477 0 0         && (gimme == G_SCALAR || MARK == SP)) {
    0          
1478 0           sv = cx->blk_eval.old_namesv;
1479 0 0         (void) hv_delete(GvHVn(PL_incgv), SvPVX_const(sv),
1480             SvCUR(sv), G_DISCARD);
1481 0           DIE(aTHX_ "%"SVf" did not return a true value", sv);
1482             }
1483 7           break;
1484             case CXt_FORMAT:
1485             #ifdef POPBLOCK
1486             POPFORMAT(cx);
1487             #else
1488 0           cx_popformat(cx);
1489             #endif
1490             #if DA_FEATURE_RETOP
1491 0           retop = cx->blk_sub.retop;
1492             #endif
1493 0           break;
1494             default:
1495 0           DIE(aTHX_ "panic: return");
1496             retop = NULL; /* suppress "uninitialized" warning */
1497             }
1498              
1499 37           TAINT_NOT;
1500 37 100         if (gimme == G_SCALAR) {
1501 3 50         if (MARK == SP) {
1502 0           *++newsp = &PL_sv_undef;
1503             } else {
1504 3           sv = SvREFCNT_inc_NN(TOPs);
1505 3 50         FREETMPS;
1506 3           *++newsp = sv_2mortal(sv);
1507             }
1508 34 100         } else if (gimme == G_LIST) {
1509 67 100         while (MARK < SP) {
1510 43           *++newsp = sv = *++MARK;
1511 43 100         if (!SvTEMP(sv) && !(SvREADONLY(sv) && SvIMMORTAL(sv)))
    50          
    0          
    0          
    0          
    0          
    0          
1512 39           sv_2mortal(SvREFCNT_inc_simple_NN(sv));
1513 43           TAINT_NOT;
1514             }
1515             }
1516 37           PL_stack_sp = newsp;
1517             #ifdef POPBLOCK
1518             LEAVE;
1519             if (type == CXt_SUB) {
1520             cxstack_ix--;
1521             POPSUB(cx, sv);
1522             LEAVESUB(sv);
1523             }
1524             PL_curpm = newpm;
1525             #else
1526 37 100         if (type == CXt_SUB) {
1527 25           cx_popsub(cx);
1528             }
1529 37 100         CX_LEAVE_SCOPE(cx);
1530 37           cx_popblock(cx);
1531 37           CX_POP(cx);
1532             #endif
1533 37 100         if (clearerr)
1534 12 50         sv_setpvn(ERRSV, "", 0);
1535             #if (!DA_FEATURE_RETOP)
1536             retop = pop_return();
1537             #endif
1538 37           return retop;
1539             }
1540              
1541 28           STATIC OP *DataAlias_pp_leavesub(pTHX) {
1542 28 50         if (++PL_markstack_ptr == PL_markstack_max)
1543 0           markstack_grow();
1544 28           *PL_markstack_ptr = cxstack[cxstack_ix].blk_oldsp;
1545 28           return DataAlias_pp_return(aTHX);
1546             }
1547              
1548 5           STATIC OP *DataAlias_pp_entereval(pTHX) {
1549             dDAforce;
1550 5           PERL_CONTEXT *iscope = da_iscope;
1551 5           I32 inside = da_inside;
1552 5 50         I32 cxi = (cxstack_ix < cxstack_max) ? cxstack_ix + 1 : cxinc();
1553             OP *ret;
1554 5           da_iscope = &cxstack[cxi];
1555 5           da_inside = 1;
1556 5           ret = PL_ppaddr[OP_ENTEREVAL](aTHX);
1557 5           da_iscope = iscope;
1558 5           da_inside = inside;
1559 5           return ret;
1560             }
1561              
1562 15           STATIC OP *DataAlias_pp_copy(pTHX) {
1563 15           dSP; dMARK;
1564             SV *sv;
1565 15 50         switch (GIMME_V) {
1566             case G_VOID:
1567 2           SP = MARK;
1568 2           break;
1569             case G_SCALAR:
1570 7 100         if (MARK == SP) {
1571 1           sv = sv_newmortal();
1572 1 50         EXTEND(SP, 1);
1573             } else {
1574 6           sv = TOPs;
1575 6 100         if (!SvTEMP(sv) || SvREFCNT(sv) != 1)
    50          
1576 5           sv = sv_mortalcopy(sv);
1577             }
1578 7           *(SP = MARK + 1) = sv;
1579 7           break;
1580             default:
1581 16 100         while (MARK < SP) {
1582 10 100         if (!SvTEMP(sv = *++MARK) || SvREFCNT(sv) != 1)
    50          
1583 8           *MARK = sv_mortalcopy(sv);
1584             }
1585             }
1586 15           RETURN;
1587             }
1588              
1589 536           STATIC void da_lvalue(pTHX_ OP *op, int list) {
1590 536           switch (op->op_type) {
1591 33           case OP_PADSV: op->op_ppaddr = DataAlias_pp_padsv;
1592 33 100         if (PadnameOUTER(
1593             PadnamelistARRAY(PL_comppad_name)[op->op_targ])
1594 2 100         && ckWARN(WARN_CLOSURE))
1595 1           Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
1596             DA_OUTER_ERR);
1597 32           break;
1598             #if DA_HAVE_OP_PADRANGE
1599             case OP_PADRANGE: {
1600 8           int start = op->op_targ;
1601 8           int count = op->op_private & OPpPADRANGE_COUNTMASK;
1602             int i;
1603 8 50         if (!list) goto bad;
1604 19 100         for(i = start; i != start+count; i++) {
1605 11 50         if (PadnameOUTER(
1606             PadnamelistARRAY(PL_comppad_name)[i])
1607 0 0         && ckWARN(WARN_CLOSURE))
1608 0           Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
1609             DA_OUTER_ERR);
1610             }
1611 8 100         if (op->op_ppaddr != DataAlias_pp_padrange_single)
1612 7           op->op_ppaddr = DataAlias_pp_padrange_list;
1613 8           } break;
1614             #endif
1615 3           case OP_AELEM: op->op_ppaddr = DataAlias_pp_aelem; break;
1616             #if (PERL_COMBI_VERSION >= 5015000)
1617             case OP_AELEMFAST_LEX:
1618             #endif
1619 15           case OP_AELEMFAST: op->op_ppaddr = DataAlias_pp_aelemfast; break;
1620 21           case OP_HELEM: op->op_ppaddr = DataAlias_pp_helem; break;
1621 3           case OP_ASLICE: op->op_ppaddr = DataAlias_pp_aslice; break;
1622 6           case OP_HSLICE: op->op_ppaddr = DataAlias_pp_hslice; break;
1623 80           case OP_GVSV: op->op_ppaddr = DataAlias_pp_gvsv; break;
1624 15           case OP_RV2SV: op->op_ppaddr = DataAlias_pp_rv2sv; break;
1625 15           case OP_RV2GV: op->op_ppaddr = DataAlias_pp_rv2gv; break;
1626             case OP_LIST:
1627 0 0         if (!list)
1628 0           goto bad;
1629             case OP_NULL:
1630 202 100         op = (op->op_flags & OPf_KIDS) ? cUNOPx(op)->op_first : NULL;
1631 545 100         while (op) {
1632 343           da_lvalue(aTHX_ op, list);
1633 343 100         op = OpSIBLING(op);
1634             }
1635 202           break;
1636             case OP_COND_EXPR:
1637 1           op = cUNOPx(op)->op_first;
1638 3 100         while ((op = OpSIBLING(op)))
    100          
1639 2           da_lvalue(aTHX_ op, list);
1640 1           break;
1641             case OP_SCOPE:
1642             case OP_LEAVE:
1643             case OP_LINESEQ:
1644 0 0         op = (op->op_flags & OPf_KIDS) ? cUNOPx(op)->op_first : NULL;
1645 0 0         while (OpHAS_SIBLING(op))
1646 0 0         op = OpSIBLING(op);
1647 0           da_lvalue(aTHX_ op, list);
1648 0           break;
1649             case OP_PUSHMARK:
1650 81 50         if (!list) goto bad;
1651 81           break;
1652             case OP_PADAV:
1653 2 50         if (!list) goto bad;
1654 2 50         if (op->op_ppaddr != DataAlias_pp_padsv)
1655 2           op->op_ppaddr = DataAlias_pp_padav;
1656 2           break;
1657             case OP_PADHV:
1658 0 0         if (!list) goto bad;
1659 0 0         if (op->op_ppaddr != DataAlias_pp_padsv)
1660 0           op->op_ppaddr = DataAlias_pp_padhv;
1661 0           break;
1662             case OP_RV2AV:
1663 16 50         if (!list) goto bad;
1664 16 100         if (op->op_ppaddr != DataAlias_pp_rv2sv)
1665 5           op->op_ppaddr = DataAlias_pp_rv2av;
1666 16           break;
1667             case OP_RV2HV:
1668 31 50         if (!list) goto bad;
1669 31 100         if (op->op_ppaddr != DataAlias_pp_rv2sv)
1670 20           op->op_ppaddr = DataAlias_pp_rv2hv;
1671 31           break;
1672             case OP_UNDEF:
1673 3 50         if (!list || (op->op_flags & OPf_KIDS))
    50          
1674             goto bad;
1675 3           break;
1676             default:
1677 1 50         bad: qerror(Perl_mess(aTHX_ DA_TARGET_ERR_AT, OutCopFILE(PL_curcop),
1678             (UV) CopLINE(PL_curcop)));
1679             }
1680 535           }
1681              
1682 89           STATIC void da_aassign(OP *op, OP *right) {
1683             OP *left, *la, *ra;
1684 89           int hash = FALSE, pad;
1685              
1686             /* make sure it fits the model exactly */
1687 89 50         if (!right || !(left = OpSIBLING(right)) || OpHAS_SIBLING(left))
    50          
    50          
    50          
1688 0           return;
1689 89 50         if (left->op_type || !(left->op_flags & OPf_KIDS))
    50          
1690 0           return;
1691 89 50         if (!(left = cUNOPx(left)->op_first) || !IS_PUSHMARK_OR_PADRANGE(left))
    100          
    50          
1692 0           return;
1693 89 50         if (!(la = OpSIBLING(left)) || OpHAS_SIBLING(la))
    50          
    100          
1694 33           return;
1695 56 100         if (la->op_flags & OPf_PARENS)
1696 19           return;
1697 37           switch (la->op_type) {
1698 9           case OP_PADHV: hash = TRUE; case OP_PADAV: pad = TRUE; break;
1699 22           case OP_RV2HV: hash = TRUE; case OP_RV2AV: pad = FALSE; break;
1700 6           default: return;
1701             }
1702 31 50         if (right->op_type || !(right->op_flags & OPf_KIDS))
    50          
1703 0           return;
1704 31 50         if (!(right = cUNOPx(right)->op_first) ||
    100          
1705 1 50         !IS_PUSHMARK_OR_PADRANGE(right))
1706 0           return;
1707 31 100         op->op_private = hash ? OPpALIASHV : OPpALIASAV;
1708 31 100         la->op_ppaddr = pad ? DataAlias_pp_padsv : DataAlias_pp_rv2sv;
1709 31 100         if (pad) {
1710 9           la->op_type = OP_PADSV;
1711             #if DA_HAVE_OP_PADRANGE
1712 9 50         if (left->op_type == OP_PADRANGE)
1713 0           left->op_ppaddr = DataAlias_pp_padrange_single;
1714 9 100         else if (right->op_type == OP_PADRANGE &&
    50          
1715 1           (right->op_flags & OPf_SPECIAL))
1716 1           right->op_ppaddr = DataAlias_pp_padrange_single;
1717             #endif
1718             }
1719 31 50         if (!(ra = OpSIBLING(right)) || OpHAS_SIBLING(ra))
    50          
    100          
1720 1           return;
1721 30 100         if (ra->op_flags & OPf_PARENS)
1722 6           return;
1723 24 100         if (hash) {
1724 11 100         if (ra->op_type != OP_PADHV && ra->op_type != OP_RV2HV)
    50          
1725 0           return;
1726             } else {
1727 13 100         if (ra->op_type != OP_PADAV && ra->op_type != OP_RV2AV)
    100          
1728 1           return;
1729             }
1730 23           ra->op_flags &= -2;
1731 23           ra->op_flags |= OPf_REF;
1732             }
1733              
1734 976           STATIC int da_transform(pTHX_ OP *op, int sib) {
1735 976           int hits = 0;
1736              
1737 4614 100         while (op) {
1738 3644           OP *kid = Nullop, *tmp;
1739 3644           int ksib = TRUE;
1740             OPCODE optype;
1741              
1742 3644 100         if (op->op_flags & OPf_KIDS)
1743 1817           kid = cUNOPx(op)->op_first;
1744              
1745 3644           ++hits;
1746 3644           switch ((optype = op->op_type)) {
1747             case OP_NULL:
1748 759           optype = (OPCODE) op->op_targ;
1749             default:
1750 2578           --hits;
1751 2578           switch (optype) {
1752             case_OP_SETSTATE_
1753             case OP_NEXTSTATE:
1754             case OP_DBSTATE:
1755 132           PL_curcop = (COP *) op;
1756 132           break;
1757             case OP_LIST:
1758 256 100         if (op->op_ppaddr == da_tag_list) {
1759 5           da_peep2(aTHX_ op);
1760 5           return hits;
1761             }
1762 251           break;
1763             }
1764 2573           break;
1765             case OP_LEAVE:
1766 64 100         if (op->op_ppaddr != da_tag_entersub)
1767 61           op->op_ppaddr = DataAlias_pp_leave;
1768             else
1769 3           hits--;
1770 64           break;
1771             case OP_LEAVESUB:
1772             case OP_LEAVESUBLV:
1773             case OP_LEAVEEVAL:
1774             case OP_LEAVETRY:
1775 29           op->op_ppaddr = DataAlias_pp_leavesub;
1776 29           break;
1777             case OP_RETURN:
1778 9           op->op_ppaddr = DataAlias_pp_return;
1779 9           break;
1780             case OP_ENTEREVAL:
1781 5           op->op_ppaddr = DataAlias_pp_entereval;
1782 5           break;
1783             case OP_CONST:
1784 154           --hits;
1785             {
1786 154           SV *sv = cSVOPx_sv(op);
1787 154           SvPADTMP_off(sv);
1788 154           SvREADONLY_on(sv);
1789             }
1790 154           break;
1791             case OP_GVSV:
1792 300 100         if (op->op_private & OPpLVAL_INTRO)
1793 1           op->op_ppaddr = DataAlias_pp_gvsv_r;
1794             else
1795 299           hits--;
1796 300           break;
1797             case OP_RV2SV:
1798             case OP_RV2AV:
1799             case OP_RV2HV:
1800 137 100         if (op->op_private & OPpLVAL_INTRO)
1801 2           op->op_ppaddr = DataAlias_pp_rv2sv_r;
1802             else
1803 135           hits--;
1804 137           break;
1805             case OP_SREFGEN:
1806 77           op->op_ppaddr = DataAlias_pp_srefgen;
1807 77           break;
1808             case OP_REFGEN:
1809 4           op->op_ppaddr = DataAlias_pp_refgen;
1810 4           break;
1811             case OP_AASSIGN:
1812 89           op->op_ppaddr = DataAlias_pp_aassign;
1813 89           op->op_private = 0;
1814 89           da_aassign(op, kid);
1815 89           MOD(kid);
1816 89           ksib = FALSE;
1817             #if DA_HAVE_OP_PADRANGE
1818 178 100         for (tmp = kid; tmp->op_type == OP_NULL &&
    50          
1819 89           (tmp->op_flags & OPf_KIDS); )
1820 89           tmp = cUNOPx(tmp)->op_first;
1821 89 100         if (tmp->op_type == OP_PADRANGE &&
    100          
1822 7           (tmp->op_flags & OPf_SPECIAL))
1823 6           da_lvalue(aTHX_ tmp, TRUE);
1824             else
1825             #endif
1826 83 50         da_lvalue(aTHX_ OpSIBLING(kid), TRUE);
1827 89           break;
1828             case OP_SASSIGN:
1829              
1830 102           op->op_ppaddr = DataAlias_pp_sassign;
1831 102           MOD(kid);
1832 102           ksib = FALSE;
1833 102 100         if (!(op->op_private & OPpASSIGN_BACKWARDS))
1834 67 50         da_lvalue(aTHX_ OpSIBLING(kid), FALSE);
1835 101           break;
1836             case OP_ANDASSIGN:
1837 15           op->op_ppaddr = DataAlias_pp_andassign;
1838             if (0)
1839             case OP_ORASSIGN:
1840 30           op->op_ppaddr = DataAlias_pp_orassign;
1841             #if DA_HAVE_OP_DORASSIGN
1842             if (0)
1843             case OP_DORASSIGN:
1844 5           op->op_ppaddr = DataAlias_pp_dorassign;
1845             #endif
1846 35           da_lvalue(aTHX_ kid, FALSE);
1847 35 50         kid = OpSIBLING(kid);
1848 35           break;
1849             case OP_UNSHIFT:
1850 6 50         if (!(tmp = OpSIBLING(kid))) break; /* array */
    50          
1851 6 100         if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
    100          
1852 4           op->op_ppaddr = DataAlias_pp_unshift;
1853 4           goto mod;
1854             case OP_PUSH:
1855 7 50         if (!(tmp = OpSIBLING(kid))) break; /* array */
    50          
1856 7 100         if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
    100          
1857 5           op->op_ppaddr = DataAlias_pp_push;
1858 5           goto mod;
1859             case OP_SPLICE:
1860 21 50         if (!(tmp = OpSIBLING(kid))) break; /* array */
    50          
1861 21 100         if (!(tmp = OpSIBLING(tmp))) break; /* offset */
    100          
1862 20 100         if (!(tmp = OpSIBLING(tmp))) break; /* length */
    100          
1863 19 100         if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
    100          
1864 15           op->op_ppaddr = DataAlias_pp_splice;
1865 15           goto mod;
1866             case OP_ANONLIST:
1867 8 100         if (!(tmp = OpSIBLING(kid))) break; /* first elem */
    100          
1868 7           op->op_ppaddr = DataAlias_pp_anonlist;
1869 7           goto mod;
1870             case OP_ANONHASH:
1871 19 100         if (!(tmp = OpSIBLING(kid))) break; /* first elem */
    100          
1872 16           op->op_ppaddr = DataAlias_pp_anonhash;
1873 96 100         mod: do MOD(tmp); while ((tmp = OpSIBLING(tmp)));
    100          
1874             }
1875              
1876 3638 100         if (sib && OpHAS_SIBLING(op)) {
    100          
1877 1498 100         if (kid)
1878 637           hits += da_transform(aTHX_ kid, ksib);
1879 1498 50         op = OpSIBLING(op);
1880             } else {
1881 2140           op = kid;
1882 2140           sib = ksib;
1883             }
1884             }
1885              
1886 970           return hits;
1887             }
1888              
1889 22510           STATIC void da_peep2(pTHX_ OP *o) {
1890             OP *k, *lsop, *pmop, *argop, *cvop, *esop;
1891             int useful;
1892 48339 100         while (o->op_ppaddr != da_tag_list
1893             #if (PERL_COMBI_VERSION >= 5031002)
1894             && o->op_ppaddr != da_tag_enter
1895             #endif
1896             ) {
1897 108243 100         while (OpHAS_SIBLING(o)) {
1898 60233 100         if ((o->op_flags & OPf_KIDS) && (k = cUNOPo->op_first)){
    100          
1899 19448           da_peep2(aTHX_ k);
1900 40785 100         } else switch (o->op_type ? o->op_type : o->op_targ) {
    100          
1901             case_OP_SETSTATE_
1902             case OP_NEXTSTATE:
1903             case OP_DBSTATE:
1904 12054           PL_curcop = (COP *) o;
1905             }
1906 60231 50         o = OpSIBLING(o);
1907             }
1908 48010 100         if (!(o->op_flags & OPf_KIDS) || !(o = cUNOPo->op_first))
    50          
1909 22181           return;
1910             }
1911             #if (PERL_COMBI_VERSION >= 5031002)
1912             if (o->op_ppaddr == da_tag_enter) {
1913             o = OpSIBLING(o);
1914             assert(o);
1915             }
1916             #endif
1917 327           lsop = o;
1918 327           useful = lsop->op_private & OPpUSEFUL;
1919 327           op_null(lsop);
1920 327           lsop->op_ppaddr = PL_ppaddr[OP_NULL];
1921 327           pmop = cLISTOPx(lsop)->op_first;
1922 327           argop = cLISTOPx(lsop)->op_last;
1923 327 50         if (!(cvop = cUNOPx(pmop)->op_first) ||
    50          
1924 327           cvop->op_ppaddr != da_tag_rv2cv) {
1925 0           Perl_warn(aTHX_ "da peep weirdness 1");
1926 0           return;
1927             }
1928 327           OpMORESIB_set(argop, cvop);
1929 327           OpLASTSIB_set(cvop, lsop);
1930 327           cLISTOPx(lsop)->op_last = cvop;
1931 327 50         if (!(esop = cvop->op_next) || esop->op_ppaddr != da_tag_entersub) {
    50          
1932 0           Perl_warn(aTHX_ "da peep weirdness 2");
1933 0           return;
1934             }
1935 327           esop->op_type = OP_ENTERSUB;
1936             #if (PERL_COMBI_VERSION >= 5031002)
1937             if (cLISTOPx(esop)->op_first->op_ppaddr == da_tag_enter) {
1938             /* the first is a dummy op we inserted to satisfy Perl_scalar/list.
1939             we can't remove it since an op_next points at it, so null it out.
1940             */
1941             OP *nullop = cLISTOPx(esop)->op_first;
1942             assert(nullop->op_type == OP_ENTER);
1943             assert(OpSIBLING(nullop));
1944             nullop->op_type = OP_NULL;
1945             nullop->op_ppaddr = PL_ppaddr[OP_NULL];
1946             }
1947             #endif
1948 327 100         if (cvop->op_flags & OPf_SPECIAL) {
1949 13           esop->op_ppaddr = DataAlias_pp_copy;
1950 13           da_peep2(aTHX_ pmop);
1951 314 100         } else if (!da_transform(aTHX_ pmop, TRUE)
1952 11 50         && !useful && ckWARN(WARN_VOID)) {
    100          
1953 1           Perl_warner(aTHX_ packWARN(WARN_VOID),
1954             "Useless use of alias");
1955             }
1956             }
1957              
1958 3069           STATIC void da_peep(pTHX_ OP *o) {
1959             dDAforce;
1960 3069           da_old_peepp(aTHX_ o);
1961 3069           ENTER;
1962 3069           SAVEVPTR(PL_curcop);
1963 3069 50         if (da_inside < 0)
1964 0           Perl_croak(aTHX_ "Data::Alias confused in da_peep (da_inside < 0)");
1965 3094 100         if (da_inside && da_iscope == &cxstack[cxstack_ix]) {
    100          
1966             OP *tmp;
1967 141 100         while ((tmp = o->op_next))
1968 116           o = tmp;
1969 25 50         if (da_transform(aTHX_ o, FALSE))
1970 25           da_inside = 2;
1971             } else {
1972 3044           da_peep2(aTHX_ o);
1973             }
1974 3067           LEAVE;
1975 3067           }
1976              
1977             #define LEX_NORMAL 10
1978             #define LEX_INTERPNORMAL 9
1979             #if DA_HAVE_LEX_KNOWNEXT
1980             #define LEX_KNOWNEXT 0
1981             #endif
1982              
1983 4659           STATIC OP *da_ck_rv2cv(pTHX_ OP *o) {
1984             dDA;
1985             SV **sp, *gvsv;
1986             OP *kid;
1987             char *s, *start_s;
1988             CV *cv;
1989             I32 inside;
1990 4659           o = da_old_ck_rv2cv(aTHX_ o);
1991             #if (PERL_COMBI_VERSION >= 5009005)
1992 4659 50         if (!PL_parser)
1993 0           return o;
1994             #endif
1995 4659 50         if (PL_lex_state != LEX_NORMAL && PL_lex_state != LEX_INTERPNORMAL)
    0          
1996 0           return o; /* not lexing? */
1997 4659           kid = cUNOPo->op_first;
1998 4659 100         if (kid->op_type != OP_GV || !DA_ACTIVE)
1999 421           return o;
2000 4238           gvsv = (SV*)kGVOP_gv;
2001             #if (PERL_COMBI_VERSION >= 5021004)
2002 4238 100         cv = SvROK(gvsv) ? (CV*)SvRV(gvsv) : GvCV((GV*)gvsv);
2003             #else
2004             cv = GvCV((GV*)gvsv);
2005             #endif
2006 4238 100         if (cv == da_cv) /* Data::Alias::alias */
2007 449           inside = 1;
2008 3789 100         else if (cv == da_cvc) /* Data::Alias::copy */
2009 17           inside = 0;
2010             else
2011 3772           return o;
2012 466 100         if (o->op_private & OPpENTERSUB_AMPER)
2013 2           return o;
2014              
2015             /* make sure the temporary ($) prototype for the parser hack is removed */
2016 464           SvPOK_off(cv);
2017              
2018             /* tag the op for later recognition */
2019 464           o->op_ppaddr = da_tag_rv2cv;
2020 464 100         if (inside)
2021 447           o->op_flags &= ~OPf_SPECIAL;
2022             else
2023 17           o->op_flags |= OPf_SPECIAL;
2024              
2025 464           start_s = s = PL_oldbufptr;
2026 512 50         while (s < PL_bufend && isSPACE(*s)) s++;
    100          
2027              
2028 464 50         if (memEQ(s, PL_tokenbuf, strlen(PL_tokenbuf))) {
2029 464           s += strlen(PL_tokenbuf);
2030 464 100         if (PL_bufptr > s) s = PL_bufptr;
2031             #if (PERL_COMBI_VERSION >= 5011002)
2032             {
2033 464           char *old_buf = SvPVX(PL_linestr);
2034 464           char *old_bufptr = PL_bufptr;
2035 464           PL_bufptr = s;
2036 464           lex_read_space(LEX_KEEP_PREVIOUS);
2037 464 50         if (SvPVX(PL_linestr) != old_buf)
2038 0           Perl_croak(aTHX_ "Data::Alias can't handle "
2039             "lexer buffer reallocation");
2040 464           s = PL_bufptr;
2041 464           PL_bufptr = old_bufptr;
2042             }
2043             #else
2044             while (s < PL_bufend && isSPACE(*s)) s++;
2045             #endif
2046             } else {
2047 0           s = "";
2048             }
2049              
2050             /* if not already done, localize da_inside to this compilation scope. */
2051             /* this ensures it will get restored if we bail out with a compile error. */
2052 464 100         if (da_iscope != &cxstack[cxstack_ix]) {
2053 37           SAVEVPTR(da_iscope);
2054 37           SAVEI32(da_inside);
2055 37           da_iscope = &cxstack[cxstack_ix];
2056             }
2057              
2058             #if (PERL_COMBI_VERSION >= 5011002)
2059             /* since perl 5.11.2, when a sub is called with parenthesized argument the */
2060             /* initial rv2cv op gets destroyed and a new one is created. deal with that. */
2061 464 100         if (da_inside < 0) {
2062 137 50         if (*s != '(' || da_inside != ~inside)
    50          
2063 0           Perl_croak(aTHX_ "Data::Alias confused in da_ck_rv2cv");
2064             } else
2065             #endif
2066             {
2067             /* save da_inside on stack, restored in da_ck_entersub */
2068 327           SPAGAIN;
2069 327 50         XPUSHs(da_inside ? &PL_sv_yes : &PL_sv_no);
    100          
2070 327           PUTBACK;
2071             }
2072             #if (PERL_COMBI_VERSION >= 5011002)
2073 464 100         if (*s == '(' && da_inside >= 0) {
    100          
2074 137           da_inside = ~inside; /* first rv2cv op (will be discarded) */
2075 137           return o;
2076             }
2077             #endif
2078 327           da_inside = inside;
2079              
2080 327 100         if (*s == '{') { /* disgusting parser hack for alias BLOCK (and copy BLOCK) */
2081             I32 shift;
2082             int tok;
2083 71           YYSTYPE yylval = PL_yylval;
2084 71           PL_bufptr = s;
2085 71           PL_expect = XSTATE;
2086 71           tok = yylex();
2087 71           PL_nexttype[PL_nexttoke++] = tok;
2088 71 100         if (tok == '{'
2089             #if PERL_COMBI_VERSION >= 5033006
2090             || tok == PERLY_BRACE_OPEN
2091             #endif
2092             ) {
2093 60           PL_nexttype[PL_nexttoke++] = DO;
2094 60           sv_setpv((SV *) cv, "$");
2095             if ((PERL_COMBI_VERSION >= 5021004) ||
2096             (PERL_COMBI_VERSION >= 5011002 &&
2097             *PL_bufptr == '(')) {
2098             /*
2099             * On 5.21.4+, PL_expect can't be
2100             * directly set as we'd like, and ends
2101             * up wrong for parsing the interior of
2102             * the block. Rectify it by injecting
2103             * a semicolon, lexing of which sets
2104             * PL_expect appropriately. On 5.11.2+,
2105             * a paren here triggers special lexer
2106             * behaviour for a parenthesised argument
2107             * list, which screws up the normal
2108             * parsing that we want to continue.
2109             * Suppress it by injecting a semicolon.
2110             * Either way, apart from this tweaking of
2111             * the lexer the semicolon is a no-op,
2112             * coming as it does just after the
2113             * opening brace of a block.
2114             */
2115 60           Move(PL_bufptr, PL_bufptr+1,
2116             PL_bufend+1-PL_bufptr, char);
2117 60           *PL_bufptr = ';';
2118 60           PL_bufend++;
2119 60           SvCUR_set(PL_linestr, SvCUR(PL_linestr)+1);
2120             }
2121             }
2122             #if DA_HAVE_LEX_KNOWNEXT
2123             if(PL_lex_state != LEX_KNOWNEXT) {
2124             PL_lex_defer = PL_lex_state;
2125             #if (PERL_COMBI_VERSION < 5021004)
2126             PL_lex_expect = PL_expect;
2127             #endif
2128             PL_lex_state = LEX_KNOWNEXT;
2129             }
2130             #endif
2131 71           PL_yylval = yylval;
2132 71 50         if ((shift = s - PL_bufptr)) { /* here comes deeper magic */
2133 71           s = SvPVX(PL_linestr);
2134 71           PL_bufptr += shift;
2135 71 50         if ((PL_oldbufptr += shift) < s)
2136 0           PL_oldbufptr = s;
2137 71 100         if ((PL_oldoldbufptr += shift) < s)
2138 25           PL_oldbufptr = s;
2139 71 100         if (PL_last_uni && (PL_last_uni += shift) < s)
    50          
2140 0           PL_last_uni = s;
2141 71 100         if (PL_last_lop && (PL_last_lop += shift) < s)
    100          
2142 36           PL_last_lop = s;
2143 71 50         if (shift > 0) {
2144 0           STRLEN len = SvCUR(PL_linestr) + 1;
2145 0 0         if (len + shift > SvLEN(PL_linestr))
2146 0           len = SvLEN(PL_linestr) - shift;
2147 0           Move(s, s + shift, len, char);
2148 0           SvCUR_set(PL_linestr, len + shift - 1);
2149             } else {
2150 71           STRLEN len = SvCUR(PL_linestr) + shift + 1;
2151 71           Move(s - shift, s, len, char);
2152 71           SvCUR_set(PL_linestr, SvCUR(PL_linestr) + shift);
2153             }
2154 71           *(PL_bufend = s + SvCUR(PL_linestr)) = '\0';
2155 71 50         if (start_s < PL_bufptr)
2156 71           memset(start_s, ' ', PL_bufptr-start_s);
2157             }
2158             }
2159 327           return o;
2160             }
2161              
2162 4343           STATIC OP *da_ck_entersub(pTHX_ OP *esop) {
2163             dDA;
2164             OP *lsop, *cvop, *pmop, *argop;
2165             I32 inside;
2166 4343 50         if (!(esop->op_flags & OPf_KIDS))
2167 0           return da_old_ck_entersub(aTHX_ esop);
2168 4343           lsop = cUNOPx(esop)->op_first;
2169 4343 50         if (!(lsop->op_type == OP_LIST ||
    100          
2170 3143 50         (lsop->op_type == OP_NULL && lsop->op_targ == OP_LIST))
2171 3143 50         || OpHAS_SIBLING(lsop) || !(lsop->op_flags & OPf_KIDS))
    50          
2172 1200           return da_old_ck_entersub(aTHX_ esop);
2173 3143           cvop = cLISTOPx(lsop)->op_last;
2174 3143 100         if (!DA_ACTIVE || cvop->op_ppaddr != da_tag_rv2cv)
2175 2816           return da_old_ck_entersub(aTHX_ esop);
2176 327           inside = da_inside;
2177 327 50         if (inside < 0)
2178 0           Perl_croak(aTHX_ "Data::Alias confused in da_ck_entersub (da_inside < 0)");
2179 327           da_inside = SvIVX(*PL_stack_sp--);
2180 327 100         SvPOK_off(inside ? da_cv : da_cvc);
    100          
2181 327           op_clear(esop);
2182 327           RenewOpc(0, esop, 1, LISTOP, OP);
2183 327           OpLASTSIB_set(lsop, esop);
2184 327 100         esop->op_type = inside ? OP_SCOPE : OP_LEAVE;
2185 327           esop->op_ppaddr = da_tag_entersub;
2186             #if (PERL_COMBI_VERSION >= 5031002)
2187             if (!inside && !OpHAS_SIBLING(lsop)) {
2188             /* esop is now a leave, and Perl_scalar/Perl_list expects at least two children.
2189             we insert it in the middle (and null it later) since Perl_scalar()
2190             tries to find the last non-(null/state) op *after* the expected enter.
2191             */
2192             OP *enterop;
2193             NewOp(0, enterop, 1, OP);
2194             enterop->op_type = OP_ENTER;
2195             enterop->op_ppaddr = da_tag_enter;
2196             cLISTOPx(esop)->op_first = enterop;
2197             OpMORESIB_set(enterop, lsop);
2198             OpLASTSIB_set(lsop, esop);
2199             }
2200             #endif
2201 327           cLISTOPx(esop)->op_last = lsop;
2202 327           lsop->op_type = OP_LIST;
2203 327           lsop->op_targ = 0;
2204 327           lsop->op_ppaddr = da_tag_list;
2205 327 100         if (inside > 1)
2206 20           lsop->op_private |= OPpUSEFUL;
2207             else
2208 307           lsop->op_private &= ~OPpUSEFUL;
2209 327           pmop = cLISTOPx(lsop)->op_first;
2210 327 100         if (inside)
2211 314           op_null(pmop);
2212 327           RenewOpc(0, pmop, 1, UNOP, OP);
2213 327           cLISTOPx(lsop)->op_first = pmop;
2214             #if (PERL_COMBI_VERSION >= 5021006)
2215 327           pmop->op_type = OP_CUSTOM;
2216             #endif
2217 327           pmop->op_next = pmop;
2218 327           cUNOPx(pmop)->op_first = cvop;
2219 327           OpLASTSIB_set(cvop, pmop);
2220 327           argop = pmop;
2221 662 50         while (OpSIBLING(argop) != cvop)
    100          
2222 335 50         argop = OpSIBLING(argop);
2223 327           cLISTOPx(lsop)->op_last = argop;
2224 327           OpLASTSIB_set(argop, lsop);
2225 327 100         if (argop->op_type == OP_NULL && inside)
    100          
2226 93           argop->op_flags &= ~OPf_SPECIAL;
2227 327           cvop->op_next = esop;
2228 327           return esop;
2229             }
2230              
2231             #if (PERL_COMBI_VERSION >= 5021007)
2232 2850           STATIC OP *da_ck_aelem(pTHX_ OP *o) { return da_old_ck_aelem(aTHX_ o); }
2233 2586           STATIC OP *da_ck_helem(pTHX_ OP *o) { return da_old_ck_helem(aTHX_ o); }
2234             #endif
2235              
2236             MODULE = Data::Alias PACKAGE = Data::Alias
2237              
2238             PROTOTYPES: DISABLE
2239              
2240             BOOT:
2241             {
2242             dDA;
2243             DA_INIT;
2244 28           da_cv = get_cv("Data::Alias::alias", TRUE);
2245 28           da_cvc = get_cv("Data::Alias::copy", TRUE);
2246 28           wrap_op_checker(OP_RV2CV, da_ck_rv2cv, &da_old_ck_rv2cv);
2247 28           wrap_op_checker(OP_ENTERSUB, da_ck_entersub, &da_old_ck_entersub);
2248             #if (PERL_COMBI_VERSION >= 5021007)
2249             {
2250             /*
2251             * The multideref peep-time optimisation, introduced in
2252             * Perl 5.21.7, is liable to incorporate into a multideref
2253             * op aelem/helem ops that we need to modify. Because our
2254             * modification of those ops gets applied late at peep
2255             * time, after the main peeper, the specialness of the
2256             * ops doesn't get a chance to inhibit incorporation
2257             * into a multideref. As an ugly hack, we disable the
2258             * multideref optimisation entirely for these op types
2259             * by hooking their checking (and not actually doing
2260             * anything in the checker).
2261             *
2262             * The multideref peep-time code has no logical
2263             * reason to look at whether the op checking is in a
2264             * non-default state. It deals with already-checked ops,
2265             * so a check hook cannot make any difference to the
2266             * future behaviour of those ops. Rather, it should,
2267             * but currently (5.23.4) doesn't, check that op_ppaddr
2268             * of the op to be incorporated has the standard value.
2269             * If the superfluous PL_check[] check goes away, this
2270             * hack will break.
2271             *
2272             * The proper fix for this problem would be to move our op
2273             * munging from peep time to op check time. When ops are
2274             * placed into an alias() wrapper they should be walked,
2275             * and the contained assignments and lvalues modified.
2276             * The modified lvalue aelem/helem ops would thereby be
2277             * made visibly non-standard in plenty of time for the
2278             * multideref peep-time code to avoid replacing them.
2279             * If the multideref code is changed to look at op_ppaddr
2280             * then that change alone will be sufficient; failing
2281             * that the op_type can be changed to OP_CUSTOM.
2282             */
2283 28           wrap_op_checker(OP_AELEM, da_ck_aelem, &da_old_ck_aelem);
2284 28           wrap_op_checker(OP_HELEM, da_ck_helem, &da_old_ck_helem);
2285             }
2286             #endif
2287 28           CvLVALUE_on(get_cv("Data::Alias::deref", TRUE));
2288 28           da_old_peepp = PL_peepp;
2289 28           PL_peepp = da_peep;
2290             }
2291              
2292             void
2293             deref(...)
2294             PREINIT:
2295 13           I32 i, n = 0;
2296             SV *sv;
2297             PPCODE:
2298 35 100         for (i = 0; i < items; i++) {
2299 27 100         if (!SvROK(ST(i))) {
2300             STRLEN z;
2301 3 100         if (SvOK(ST(i)))
    50          
    50          
2302 1 50         Perl_croak(aTHX_ DA_DEREF_ERR, SvPV(ST(i), z));
2303 2 100         if (ckWARN(WARN_UNINITIALIZED))
2304 1           Perl_warner(aTHX_ packWARN(WARN_UNINITIALIZED),
2305             "Use of uninitialized value in deref");
2306 1           continue;
2307             }
2308 24           sv = SvRV(ST(i));
2309 24           switch (SvTYPE(sv)) {
2310             I32 x;
2311             case SVt_PVAV:
2312 4 100         if (!(x = av_len((AV *) sv) + 1))
2313 1           continue;
2314 3           SP += x;
2315 3           break;
2316             case SVt_PVHV:
2317 3 50         if (!(x = HvKEYS(sv)))
    100          
2318 1           continue;
2319 2           SP += x * 2;
2320 2           break;
2321             case SVt_PVCV:
2322 1           Perl_croak(aTHX_ "Can't deref subroutine reference");
2323             case SVt_PVFM:
2324 1           Perl_croak(aTHX_ "Can't deref format reference");
2325             case SVt_PVIO:
2326 1           Perl_croak(aTHX_ "Can't deref filehandle reference");
2327             default:
2328 14           SP++;
2329             }
2330 19           ST(n++) = ST(i);
2331             }
2332 8 50         EXTEND(SP, 0);
2333 27 100         for (i = 0; n--; ) {
2334 19           SV *sv = SvRV(ST(n));
2335 19           I32 x = SvTYPE(sv);
2336 19 100         if (x == SVt_PVAV) {
2337 3 50         i -= x = AvFILL((AV *) sv) + 1;
2338 3 50         Copy(AvARRAY((AV *) sv), SP + i + 1, INT2SIZE(x), SV *);
2339 16 100         } else if (x == SVt_PVHV) {
2340             HE *entry;
2341 2           HV *hv = (HV *) sv;
2342 2           i -= x = hv_iterinit(hv) * 2;
2343 2           PUTBACK;
2344 6 100         while ((entry = hv_iternext(hv))) {
2345 4           sv = hv_iterkeysv(entry);
2346 4           SvREADONLY_on(sv);
2347 4           SPAGAIN;
2348 4           SP[++i] = sv;
2349 4           sv = hv_iterval(hv, entry);
2350 4           SPAGAIN;
2351 4           SP[++i] = sv;
2352             }
2353 2           i -= x;
2354             } else {
2355 14           SP[i--] = sv;
2356             }
2357             }