/home/travis/build/MoarVM/MoarVM/src/6model/reprs/MVMHash.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Representation used by VM-level hashes. */ |
2 | | |
3 | | struct MVMHashEntry { |
4 | | /* value object */ |
5 | | MVMObject *value; |
6 | | |
7 | | /* the uthash hash handle inline struct, including the key. */ |
8 | | UT_hash_handle hash_handle; |
9 | | }; |
10 | | |
11 | | struct MVMHashBody { |
12 | | /* uthash updates this pointer directly. */ |
13 | | MVMHashEntry *hash_head; |
14 | | }; |
15 | | struct MVMHash { |
16 | | MVMObject common; |
17 | | MVMHashBody body; |
18 | | }; |
19 | | |
20 | | /* Function for REPR setup. */ |
21 | | const MVMREPROps * MVMHash_initialize(MVMThreadContext *tc); |
22 | | |
23 | | #define MVM_HASH_BIND(tc, hash, key, value) \ |
24 | 2.22M | do { \ |
25 | 2.22M | if (MVM_LIKELY(!MVM_is_null(tc, (MVMObject *)key) && REPR(key)->ID == MVM_REPR_ID_MVMString \ |
26 | 2.22M | && IS_CONCRETE(key))) { \ |
27 | 2.22M | HASH_ADD_KEYPTR_VM_STR(tc, hash_handle, hash, key, value); \ |
28 | 2.22M | } \ |
29 | 0 | else { \ |
30 | 0 | MVM_exception_throw_adhoc(tc, "Hash keys must be concrete strings"); \ |
31 | 0 | } \ |
32 | 2.22M | } while (0); |
33 | | |
34 | | #define MVM_HASH_GET(tc, hash, key, value) \ |
35 | 26.7M | do { \ |
36 | 26.7M | if (MVM_LIKELY(!MVM_is_null(tc, (MVMObject *)key) && REPR(key)->ID == MVM_REPR_ID_MVMString \ |
37 | 26.7M | && IS_CONCRETE(key))) { \ |
38 | 26.7M | HASH_FIND_VM_STR(tc, hash_handle, hash, key, value); \ |
39 | 26.7M | } \ |
40 | 18.4E | else { \ |
41 | 18.4E | MVM_exception_throw_adhoc(tc, "Hash keys must be concrete strings"); \ |
42 | 18.4E | } \ |
43 | 26.7M | } while (0); |
44 | | |
45 | 987k | #define MVM_HASH_KEY(entry) ((MVMString *)(entry)->hash_handle.key) |
46 | | |
47 | 1.21k | #define MVM_HASH_DESTROY(tc, hash_handle, hashentry_type, head_node) do { \ |
48 | 1.21k | hashentry_type *current, *tmp; \ |
49 | 1.21k | unsigned bucket_tmp; \ |
50 | 3.59k | HASH_ITER(hash_handle, head_node, current, tmp, bucket_tmp) { \ |
51 | 3.59k | if (current != head_node) \ |
52 | 2.47k | MVM_free(current); \ |
53 | 3.59k | } \ |
54 | 1.21k | tmp = head_node; \ |
55 | 1.21k | HASH_CLEAR(tc, hash_handle, head_node); \ |
56 | 1.21k | MVM_free(tmp); \ |
57 | 1.21k | } while (0) |
58 | | |
59 | | void MVMHash_at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister *result, MVMuint16 kind); |
60 | | void MVMHash_bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister value, MVMuint16 kind); |