| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
namespace xs { |
|
4
|
|
|
|
|
|
|
|
|
5
|
4
|
|
|
|
|
|
Hash::Hash (const std::initializer_list>& l) { |
|
6
|
2
|
50
|
|
|
|
|
sv = (SV*)newHV(); |
|
7
|
2
|
50
|
|
|
|
|
reserve(l.size()); |
|
8
|
2
|
|
|
|
|
|
auto end = l.end(); |
|
9
|
6
|
100
|
|
|
|
|
for (auto ptr = l.begin(); ptr != end; ++ptr) store(ptr->first, ptr->second); |
|
|
|
50
|
|
|
|
|
|
|
10
|
2
|
|
|
|
|
|
} |
|
11
|
|
|
|
|
|
|
|
|
12
|
124
|
|
|
|
|
|
void Hash::store (const panda::string_view& key, const Scalar& v, U32 hash) { |
|
13
|
124
|
100
|
|
|
|
|
if (!sv) throw std::logic_error("store: empty object"); |
|
|
|
50
|
|
|
|
|
|
|
14
|
123
|
|
|
|
|
|
SV* val = v; |
|
15
|
123
|
100
|
|
|
|
|
if (val) SvREFCNT_inc_simple_void_NN(val); |
|
16
|
1
|
50
|
|
|
|
|
else val = newSV(0); |
|
17
|
123
|
50
|
|
|
|
|
SV** ret = hv_store((HV*)sv, key.data(), key.length(), val, hash); |
|
18
|
123
|
50
|
|
|
|
|
if (!ret) SvREFCNT_dec_NN(val); |
|
|
|
0
|
|
|
|
|
|
|
19
|
123
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
1
|
|
|
|
|
|
U32 Hash::push_on_stack (SV** sp) const { |
|
22
|
1
|
|
|
|
|
|
HV* hv = (HV*)sv; |
|
23
|
1
|
50
|
|
|
|
|
auto sz = HvUSEDKEYS(hv) * 2; |
|
|
|
0
|
|
|
|
|
|
|
24
|
1
|
50
|
|
|
|
|
if (!sz) return 0; |
|
25
|
1
|
50
|
|
|
|
|
EXTEND(sp, (I32)sz); |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
26
|
1
|
|
|
|
|
|
STRLEN hvmax = HvMAX(hv); |
|
27
|
1
|
|
|
|
|
|
HE** hvarr = HvARRAY(hv); |
|
28
|
9
|
100
|
|
|
|
|
for (STRLEN bucket_num = 0; bucket_num <= hvmax; ++bucket_num) |
|
29
|
10
|
100
|
|
|
|
|
for (const HE* he = hvarr[bucket_num]; he; he = HeNEXT(he)) { |
|
30
|
2
|
50
|
|
|
|
|
*++sp = sv_2mortal(newSVpvn(HeKEY(he), HeKLEN(he))); |
|
|
|
50
|
|
|
|
|
|
|
31
|
2
|
50
|
|
|
|
|
*++sp = sv_2mortal(SvREFCNT_inc_NN(HeVAL(he))); |
|
32
|
|
|
|
|
|
|
} |
|
33
|
1
|
|
|
|
|
|
return sz; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
} |