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
|
|
|
|
|
|
|
} |