Coverage Report

Created: 2017-04-15 07:07

/home/travis/build/MoarVM/MoarVM/src/core/dll.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
0
int MVM_dll_load(MVMThreadContext *tc, MVMString *name, MVMString *path) {
4
0
    MVMDLLRegistry *entry;
5
0
    char *cpath;
6
0
    DLLib *lib;
7
0
8
0
    uv_mutex_lock(&tc->instance->mutex_dll_registry);
9
0
10
0
    MVM_HASH_GET(tc, tc->instance->dll_registry, name, entry);
11
0
12
0
    /* already loaded */
13
0
    if (entry && entry->lib) {
14
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
15
0
        return 0;
16
0
    }
17
0
18
0
    MVMROOT(tc, name, {
19
0
        MVMROOT(tc, path, {
20
0
            path = MVM_file_in_libpath(tc, path);
21
0
        });
22
0
    });
23
0
24
0
    cpath = MVM_string_utf8_c8_encode_C_string(tc, path);
25
0
    lib = MVM_nativecall_load_lib(cpath);
26
0
27
0
    if (!lib) {
28
0
        char *waste[] = { cpath, NULL };
29
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
30
0
        MVM_exception_throw_adhoc_free(tc, waste, "failed to load library '%s'", cpath);
31
0
    }
32
0
33
0
    MVM_free(cpath);
34
0
35
0
    if (!entry) {
36
0
        entry = MVM_malloc(sizeof *entry);
37
0
        entry->name = name;
38
0
        entry->refcount = 0;
39
0
40
0
        MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&entry->name,
41
0
            "DLL name");
42
0
        MVM_HASH_BIND(tc, tc->instance->dll_registry, name, entry);
43
0
        MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&entry->hash_handle.key,
44
0
            "DLL name hash key");
45
0
    }
46
0
47
0
    entry->lib = lib;
48
0
49
0
    uv_mutex_unlock(&tc->instance->mutex_dll_registry);
50
0
51
0
    return 1;
52
0
}
53
54
0
int MVM_dll_free(MVMThreadContext *tc, MVMString *name) {
55
0
    MVMDLLRegistry *entry;
56
0
57
0
    uv_mutex_lock(&tc->instance->mutex_dll_registry);
58
0
59
0
    MVM_HASH_GET(tc, tc->instance->dll_registry, name, entry);
60
0
61
0
    if (!entry) {
62
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
63
0
        MVM_exception_throw_adhoc(tc, "cannot free non-existent library");
64
0
    }
65
0
66
0
    /* already freed */
67
0
    if (!entry->lib) {
68
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
69
0
        return 0;
70
0
    }
71
0
72
0
    if (entry->refcount > 0) {
73
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
74
0
        MVM_exception_throw_adhoc(tc, "cannot free in-use library");
75
0
    }
76
0
77
0
    MVM_nativecall_free_lib(entry->lib);
78
0
    entry->lib = NULL;
79
0
80
0
    uv_mutex_unlock(&tc->instance->mutex_dll_registry);
81
0
82
0
    return 1;
83
0
}
84
85
MVMObject * MVM_dll_find_symbol(MVMThreadContext *tc, MVMString *lib,
86
0
        MVMString *sym) {
87
0
    MVMDLLRegistry *entry;
88
0
    MVMDLLSym *obj;
89
0
    char *csym;
90
0
    void *address;
91
0
92
0
    uv_mutex_lock(&tc->instance->mutex_dll_registry);
93
0
94
0
    MVM_HASH_GET(tc, tc->instance->dll_registry, lib, entry);
95
0
96
0
    if (!entry) {
97
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
98
0
        MVM_exception_throw_adhoc(tc,
99
0
                "cannot find symbol in non-existent library");
100
0
    }
101
0
102
0
    if (!entry->lib) {
103
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
104
0
        MVM_exception_throw_adhoc(tc,
105
0
                "cannot find symbol in unloaded library");
106
0
    }
107
0
108
0
    csym = MVM_string_utf8_c8_encode_C_string(tc, sym);
109
0
    address = MVM_nativecall_find_sym(entry->lib, csym);
110
0
    MVM_free(csym);
111
0
112
0
    if (!address) {
113
0
        uv_mutex_unlock(&tc->instance->mutex_dll_registry);
114
0
        return NULL;
115
0
    }
116
0
117
0
    obj = (MVMDLLSym *)MVM_repr_alloc_init(tc,
118
0
            tc->instance->raw_types.RawDLLSym);
119
0
    obj->body.address = address;
120
0
    obj->body.dll = entry;
121
0
122
0
    entry->refcount++;
123
0
124
0
    uv_mutex_unlock(&tc->instance->mutex_dll_registry);
125
0
    return (MVMObject *)obj;
126
0
}
127
128
0
void MVM_dll_drop_symbol(MVMThreadContext *tc, MVMObject *obj) {
129
0
    MVMDLLSym *sym;
130
0
    MVMDLLRegistry *dll;
131
0
132
0
    if (REPR(obj)->ID != MVM_REPR_ID_MVMDLLSym)
133
0
        MVM_exception_throw_adhoc(tc,
134
0
                "unexpected object with REPR other than MVMDLLSym");
135
0
136
0
    sym = (MVMDLLSym *)obj;
137
0
    dll = sym->body.dll;
138
0
139
0
    if (!dll)
140
0
        return;
141
0
142
0
    MVM_decr(&dll->refcount);
143
0
144
0
    sym->body.address = NULL;
145
0
    sym->body.dll = NULL;
146
0
}