line |
true |
false |
branch |
15
|
5018 |
6 |
if (SvROK(source)) { |
17
|
5006 |
12 |
if (type == SVt_PVHV && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
5006 |
0 |
if (type == SVt_PVHV && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
5005 |
1 |
if (type == SVt_PVHV && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
5005 |
0 |
if (type == SVt_PVHV && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
21
|
12 |
1 |
else if (type == SVt_PVAV && (flags & (MergeFlags::ARRAY_MERGE|MergeFlags::ARRAY_CONCAT)) && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
10 |
2 |
else if (type == SVt_PVAV && (flags & (MergeFlags::ARRAY_MERGE|MergeFlags::ARRAY_CONCAT)) && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
10 |
0 |
else if (type == SVt_PVAV && (flags & (MergeFlags::ARRAY_MERGE|MergeFlags::ARRAY_CONCAT)) && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
9 |
1 |
else if (type == SVt_PVAV && (flags & (MergeFlags::ARRAY_MERGE|MergeFlags::ARRAY_CONCAT)) && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
|
9 |
0 |
else if (type == SVt_PVAV && (flags & (MergeFlags::ARRAY_MERGE|MergeFlags::ARRAY_CONCAT)) && dest != NULL && SvROK(dest) && SvTYPE(SvRV(dest)) == type) { |
26
|
2 |
2 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
2 |
0 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
2 |
0 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
0 |
2 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
28
|
3 |
1 |
if (flags & MergeFlags::COPY_SOURCE) { // deep copy reference value |
29
|
3 |
0 |
SV* copy = newRV_noinc(clone(SvRV(source), 0).detach()); |
|
3 |
0 |
SV* copy = newRV_noinc(clone(SvRV(source), 0).detach()); |
30
|
3 |
0 |
SvSetSV_nosteal(dest, copy); |
|
3 |
0 |
SvSetSV_nosteal(dest, copy); |
31
|
3 |
0 |
SvREFCNT_dec(copy); |
35
|
1 |
0 |
SvSetSV_nosteal(dest, source); |
38
|
2 |
4 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
1 |
1 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
1 |
0 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
|
0 |
1 |
if ((flags & MergeFlags::LAZY) && SvOK(dest)) return; |
39
|
5 |
0 |
SvSetSV_nosteal(dest, source); |
44
|
2 |
5020 |
if (dest == source) return; // nothing to merge, avoid recursive cycle-reference self-merge |
45
|
1 |
5019 |
if (depth > MERGE_MAX_DEPTH) throw MERGE_DEPTH_ERROR; |
|
1 |
0 |
if (depth > MERGE_MAX_DEPTH) throw MERGE_DEPTH_ERROR; |
49
|
1 |
5018 |
if (!hvarr) return; |
50
|
40144 |
18 |
for (STRLEN i = 0; i <= hvmax; ++i) { |
52
|
5050 |
35144 |
for (entry = hvarr[i]; entry; entry = HeNEXT(entry)) { |
55
|
3 |
5047 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(valueSV)) continue; // skip undefs |
|
1 |
2 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(valueSV)) continue; // skip undefs |
|
1 |
0 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(valueSV)) continue; // skip undefs |
|
1 |
0 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(valueSV)) continue; // skip undefs |
56
|
3 |
5046 |
if ((flags & MergeFlags::DELETE_UNDEF) && !SvOK(valueSV)) { |
|
2 |
1 |
if ((flags & MergeFlags::DELETE_UNDEF) && !SvOK(valueSV)) { |
|
2 |
0 |
if ((flags & MergeFlags::DELETE_UNDEF) && !SvOK(valueSV)) { |
|
2 |
0 |
if ((flags & MergeFlags::DELETE_UNDEF) && !SvOK(valueSV)) { |
57
|
2 |
0 |
hv_deletehek(dest, hek, G_DISCARD); |
60
|
10 |
5037 |
if (MERGE_CAN_LAZY(flags, valueSV)) { |
|
6 |
4 |
if (MERGE_CAN_LAZY(flags, valueSV)) { |
61
|
6 |
0 |
SV** elemref = hv_fetchhek(dest, hek, 0); |
62
|
2 |
4 |
if (elemref != NULL && SvOK(*elemref)) continue; |
|
0 |
2 |
if (elemref != NULL && SvOK(*elemref)) continue; |
|
0 |
0 |
if (elemref != NULL && SvOK(*elemref)) continue; |
|
0 |
0 |
if (elemref != NULL && SvOK(*elemref)) continue; |
64
|
5038 |
7 |
if (MERGE_CAN_ALIAS(flags, valueSV)) { // make aliases for simple values |
|
32 |
5006 |
if (MERGE_CAN_ALIAS(flags, valueSV)) { // make aliases for simple values |
66
|
32 |
0 |
hv_storehek(dest, hek, valueSV); |
69
|
5013 |
0 |
SV* destSV = *(hv_fetchhek(dest, hek, 1)); |
70
|
13 |
5000 |
_elem_merge(aTHX_ destSV, valueSV, flags, depth); |
76
|
0 |
9 |
if (dest == source) return; // nothing to merge, avoid recursive cycle-reference self-merge |
77
|
0 |
9 |
if (depth > MERGE_MAX_DEPTH) throw MERGE_DEPTH_ERROR; |
|
0 |
0 |
if (depth > MERGE_MAX_DEPTH) throw MERGE_DEPTH_ERROR; |
80
|
0 |
9 |
if (SvREADONLY(dest)) Perl_croak_no_modify(); |
84
|
2 |
7 |
if (flags & MergeFlags::ARRAY_CONCAT) { |
88
|
0 |
2 |
if (flags & MergeFlags::COPY_SOURCE) { |
89
|
0 |
0 |
while (srcfill-- >= 0) { |
91
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
|
0 |
0 |
dstlist[savei++] = elem == NULL ? newSV(0) : clone(elem, 0).detach(); |
94
|
6 |
2 |
while (srcfill-- >= 0) { |
96
|
0 |
6 |
if (elem == NULL) dstlist[savei++] = newSV(0); |
|
0 |
0 |
if (elem == NULL) dstlist[savei++] = newSV(0); |
108
|
19 |
7 |
for (int i = 0; i <= srcfill; ++i) { |
110
|
0 |
19 |
if (elem == NULL) continue; // skip empty slots |
111
|
2 |
17 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(elem)) continue; // skip undefs |
|
1 |
1 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(elem)) continue; // skip undefs |
|
1 |
0 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(elem)) continue; // skip undefs |
|
1 |
0 |
if ((flags & MergeFlags::SKIP_UNDEF) && !SvOK(elem)) continue; // skip undefs |
112
|
6 |
12 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
|
4 |
2 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
|
4 |
0 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
|
0 |
4 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
|
0 |
0 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
|
0 |
0 |
if (MERGE_CAN_LAZY(flags, elem) && dstlist[i] && SvOK(dstlist[i])) continue; |
113
|
13 |
1 |
if (MERGE_CAN_ALIAS(flags, elem)) { // hardcode for speed - make aliases for simple values |
|
11 |
2 |
if (MERGE_CAN_ALIAS(flags, elem)) { // hardcode for speed - make aliases for simple values |
115
|
11 |
0 |
if (AvREAL(dest)) SvREFCNT_dec(dstlist[i]); |
|
11 |
0 |
if (AvREAL(dest)) SvREFCNT_dec(dstlist[i]); |
119
|
0 |
3 |
if (!dstlist[i]) dstlist[i] = newSV(0); |
|
0 |
0 |
if (!dstlist[i]) dstlist[i] = newSV(0); |
120
|
3 |
0 |
_elem_merge(aTHX_ dstlist[i], elem, flags, depth); |
122
|
0 |
7 |
if (AvFILLp(dest) < srcfill) AvFILLp(dest) = srcfill; |
127
|
2 |
18 |
if (!dest) dest = Hash::create(); |
128
|
3 |
15 |
else if (flags & MergeFlags::COPY_DEST) dest = clone(dest, 0); |
|
3 |
0 |
else if (flags & MergeFlags::COPY_DEST) dest = clone(dest, 0); |
129
|
17 |
3 |
if (source) _hash_merge(aTHX_ dest, source, flags, 1); |
134
|
0 |
0 |
if (!dest) dest = Array::create(); |
135
|
0 |
0 |
else if (flags & MergeFlags::COPY_DEST) dest = clone(dest, 0); |
|
0 |
0 |
else if (flags & MergeFlags::COPY_DEST) dest = clone(dest, 0); |
136
|
0 |
0 |
if (source) _array_merge(aTHX_ dest, source, flags | MergeFlags::ARRAY_MERGE, 1); |
141
|
1 |
7 |
if ((flags & MergeFlags::COPY_ALL) && dest) dest = clone(dest, 0); |
|
1 |
0 |
if ((flags & MergeFlags::COPY_ALL) && dest) dest = clone(dest, 0); |
|
1 |
7 |
if ((flags & MergeFlags::COPY_ALL) && dest) dest = clone(dest, 0); |
142
|
8 |
0 |
_elem_merge(aTHX_ dest, source ? source.get() : &PL_sv_undef, flags, 0); |