line |
true |
false |
branch |
29
|
38 |
0 |
Sv ret = Sv::create(); |
32
|
10 |
28 |
if (flags & CloneFlags::TRACK_REFS) { |
35
|
10 |
0 |
_clone(aTHX_ ret, source, crossdata, 0); |
37
|
2 |
10 |
for (const auto& row : data.weakrefs) { // post process weak refs that appeared before their strong refs |
38
|
2 |
0 |
auto it = data.map.find(row.key); |
39
|
1 |
1 |
if (it == end) continue; |
40
|
1 |
0 |
SvSetSV_nosteal(row.dest, it->second); |
|
1 |
0 |
SvSetSV_nosteal(row.dest, it->second); |
41
|
1 |
0 |
sv_rvweaken(row.dest); |
44
|
26 |
2 |
else _clone(aTHX_ ret, source, crossdata, 0); |
50
|
2 |
15150 |
if (depth > CLONE_MAX_DEPTH) throw std::invalid_argument("clone: max depth (5000) reached, it looks like you passed a cycled structure"); |
|
2 |
0 |
if (depth > CLONE_MAX_DEPTH) throw std::invalid_argument("clone: max depth (5000) reached, it looks like you passed a cycled structure"); |
52
|
5051 |
10099 |
if (SvROK(source)) { // reference |
56
|
5049 |
2 |
if (val_type == SVt_PVCV || val_type == SVt_PVIO) { // CV and IO cannot be copied - just set reference to the same SV |
|
2 |
5047 |
if (val_type == SVt_PVCV || val_type == SVt_PVIO) { // CV and IO cannot be copied - just set reference to the same SV |
57
|
4 |
0 |
SvSetSV_nosteal(dest, source); |
|
4 |
0 |
SvSetSV_nosteal(dest, source); |
58
|
2 |
2 |
if (SvWEAKREF(source)) sv_rvweaken(dest); |
|
2 |
0 |
if (SvWEAKREF(source)) sv_rvweaken(dest); |
63
|
25 |
5022 |
if (xdata) { |
64
|
25 |
0 |
auto it = xdata->map.find(id); |
65
|
5 |
20 |
if (it != xdata->map.end()) { |
66
|
5 |
0 |
SvSetSV_nosteal(dest, it->second); |
|
5 |
0 |
SvSetSV_nosteal(dest, it->second); |
67
|
1 |
4 |
if (SvWEAKREF(source)) sv_rvweaken(dest); |
|
1 |
0 |
if (SvWEAKREF(source)) sv_rvweaken(dest); |
70
|
2 |
18 |
if (SvWEAKREF(source)) { |
72
|
2 |
0 |
xdata->weakrefs.push_back({dest, id}); |
81
|
5010 |
30 |
if (is_object) { |
82
|
5010 |
0 |
auto mg = mg_findext(source_val, PERL_MAGIC_ext, &clone_marker); |
83
|
2 |
5008 |
if (mg) { |
86
|
5008 |
0 |
else if ((cloneGV = gv_fetchmeth(SvSTASH(source_val), HOOK_METHOD, HOOK_METHLEN, 0))) { |
|
3 |
5005 |
else if ((cloneGV = gv_fetchmeth(SvSTASH(source_val), HOOK_METHOD, HOOK_METHLEN, 0))) { |
88
|
3 |
0 |
sv_magicext(source_val, NULL, PERL_MAGIC_ext, &clone_marker, (const char*)xdata, 0); |
89
|
3 |
0 |
dSP; ENTER; SAVETMPS; |
|
3 |
0 |
dSP; ENTER; SAVETMPS; |
90
|
0 |
3 |
PUSHMARK(SP); |
|
0 |
0 |
PUSHMARK(SP); |
91
|
0 |
3 |
XPUSHs(source); |
|
0 |
0 |
XPUSHs(source); |
93
|
3 |
0 |
int count = call_sv((SV*)GvCV(cloneGV), G_SCALAR); |
96
|
3 |
3 |
while (count--) retval = POPs; |
97
|
3 |
0 |
if (retval) SvSetSV(dest, retval); |
|
3 |
0 |
if (retval) SvSetSV(dest, retval); |
|
3 |
0 |
if (retval) SvSetSV(dest, retval); |
99
|
3 |
0 |
FREETMPS; LEAVE; |
|
3 |
0 |
FREETMPS; LEAVE; |
|
3 |
0 |
FREETMPS; LEAVE; |
101
|
3 |
0 |
sv_unmagicext(source_val, PERL_MAGIC_ext, &clone_marker); |
102
|
1 |
2 |
if (xdata) xdata->map[id] = dest; |
|
1 |
0 |
if (xdata) xdata->map[id] = dest; |
107
|
5037 |
0 |
SV* refval = newSV(0); |
108
|
5037 |
0 |
sv_upgrade(dest, SVt_RV); |
112
|
5007 |
30 |
if (is_object) sv_bless(dest, SvSTASH(source_val)); // cloning an object without any specific clone behavior |
|
5007 |
0 |
if (is_object) sv_bless(dest, SvSTASH(source_val)); // cloning an object without any specific clone behavior |
113
|
16 |
5021 |
if (xdata) xdata->map[id] = dest; |
|
16 |
0 |
if (xdata) xdata->map[id] = dest; |
114
|
35 |
5002 |
_clone(aTHX_ refval, source_val, xdata, depth+1); |
130
|
5062 |
0 |
SvSetSV_nosteal(dest, source); |
145
|
45 |
17 |
for (SSize_t i = 0; i <= srcfill; ++i) { |
147
|
45 |
0 |
if (srcval != NULL) { // if not empty slot |
159
|
0 |
5018 |
if (!hvarr) return; |
161
|
40144 |
20 |
for (STRLEN i = 0; i <= hvmax; ++i) { |
163
|
10032 |
35146 |
for (entry = hvarr[i]; entry; entry = HeNEXT(entry)) { |
165
|
10032 |
0 |
SV* elem = newSV(0); |
166
|
10032 |
0 |
hv_storehek((HV*)dest, hek, elem); |
167
|
5034 |
4998 |
_clone(aTHX_ elem, HeVAL(entry), xdata, depth+1); |
179
|
7 |
0 |
} |
|
7 |
0 |
} |