File Coverage

hax/OP_HELEMEXISTSOR.c.inc
Criterion Covered Total %
statement 0 27 0.0
branch 0 16 0.0
condition n/a
subroutine n/a
pod n/a
total 0 43 0.0


line stmt bran cond sub pod time code
1             /* vi: set ft=c : */
2              
3             #define newHELEMEXISTSOROP(flags, helem, other) S_newHELEMEXISTSOROP(aTHX_ flags, helem, other)
4              
5             #if defined(OPpHELEMEXISTSOR_DELETE)
6             /* For now this is not in any Perl release but hopefully soon; maybe in time
7             * for 5.37.7
8             * https://github.com/Perl/perl5/pull/20598
9             */
10              
11             static OP *S_newHELEMEXISTSOROP(pTHX_ U32 flags, OP *helem, OP *other)
12             {
13             return newLOGOP(OP_HELEMEXISTSOR, flags, helem, other);
14             }
15              
16             #else
17              
18             enum {
19             OPpHELEMEXISTSOR_DELETE = (1<<7),
20             };
21              
22 0           static OP *pp_helemexistsor(pTHX)
23             {
24 0           dSP;
25 0           SV *keysv = POPs;
26 0           HV *hv = MUTABLE_HV(POPs);
27 0           bool is_delete = PL_op->op_private & OPpHELEMEXISTSOR_DELETE;
28              
29             assert(SvTYPE(hv) == SVt_PVHV);
30              
31 0           bool hv_is_magical = UNLIKELY(SvMAGICAL(hv));
32              
33             SV *val = NULL;
34              
35             /* For magical HVs we have to ensure we invoke the EXISTS method first. For
36             * regular HVs we can just skip this and use the "pointer or NULL" result
37             * of the real hv_* functions
38             */
39 0 0         if(hv_is_magical && !hv_exists_ent(hv, keysv, 0))
    0          
40             goto other;
41              
42 0 0         if(is_delete) {
43 0           val = hv_delete_ent(hv, keysv, 0, 0);
44             }
45             else {
46 0           HE *he = hv_fetch_ent(hv, keysv, 0, 0);
47 0 0         val = he ? HeVAL(he) : NULL;
48              
49             /* A magical HV hasn't yet actually invoked the FETCH method. We must ask
50             * it to do so now
51             */
52 0 0         if(hv_is_magical && val)
53 0 0         SvGETMAGIC(val);
54             }
55              
56 0 0         if(!val) {
57             other:
58 0           PUTBACK;
59 0           return cLOGOP->op_other;
60             }
61              
62 0           PUSHs(val);
63 0           RETURN;
64             }
65              
66 0           static OP *S_newHELEMEXISTSOROP(pTHX_ U32 flags, OP *helem, OP *other)
67             {
68             assert(helem->op_type == OP_HELEM);
69              
70             OP *o = newLOGOP_CUSTOM(&pp_helemexistsor, flags, helem, other);
71              
72 0           OP *hvop = cBINOPx(helem)->op_first;
73 0 0         OP *keyop = OpSIBLING(hvop);
74              
75 0           helem->op_targ = helem->op_type;
76 0           helem->op_type = OP_NULL;
77 0           helem->op_ppaddr = PL_ppaddr[OP_NULL];
78              
79             /* o is actually the structural-containing OP_NULL */
80 0           OP *real_o = cUNOPo->op_first;
81              
82 0           keyop->op_next = real_o;
83              
84 0           return o;
85             }
86              
87             #endif