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