Coverage Report

Created: 2017-04-15 07:07

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/MVMContext.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* This representation's function pointer table. */
4
static const MVMREPROps MVMContext_this_repr;
5
6
/* Creates a new type object of this representation, and associates it with
7
 * the given HOW. Also sets the invocation protocol handler in the STable. */
8
130
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
130
    MVMSTable *st = MVM_gc_allocate_stable(tc, &MVMContext_this_repr, HOW);
10
130
11
130
    MVMROOT(tc, st, {
12
130
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
130
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
130
        st->size = sizeof(MVMContext);
15
130
    });
16
130
17
130
    return st->WHAT;
18
130
}
19
20
/* Copies the body of one object to another. */
21
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
22
0
    MVM_panic(MVM_exitcode_NYI, "MVMContext copy_to NYI");
23
0
}
24
25
/* Adds held objects to the GC worklist. */
26
651
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
27
651
    MVMContextBody *body = (MVMContextBody *)data;
28
651
    MVM_gc_worklist_add(tc, worklist, &body->context);
29
651
}
30
31
2.82k
static void at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister *result, MVMuint16 kind) {
32
2.82k
    MVMString      *name  = (MVMString *)key;
33
2.82k
    MVMContextBody *body  = (MVMContextBody *)data;
34
2.82k
    MVMFrame       *frame = body->context;
35
2.82k
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
36
2.82k
    if (!lexical_names) {
37
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
38
0
        char *waste[] = { c_name, NULL };
39
0
        MVM_exception_throw_adhoc_free(tc, waste,
40
0
            "Lexical with name '%s' does not exist in this frame",
41
0
                c_name);
42
0
    }
43
2.82k
    MVM_HASH_GET(tc, lexical_names, name, entry);
44
2.82k
    if (!entry) {
45
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
46
0
        char *waste[] = { c_name, NULL };
47
0
        MVM_exception_throw_adhoc_free(tc, waste,
48
0
            "Lexical with name '%s' does not exist in this frame",
49
0
                c_name);
50
0
    }
51
2.82k
    if (frame->static_info->body.lexical_types[entry->value] != kind) {
52
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
53
0
        char *waste[] = { c_name, NULL };
54
0
        MVM_exception_throw_adhoc_free(tc, waste,
55
0
            "Lexical with name '%s' has a different type in this frame",
56
0
                c_name);
57
0
    }
58
2.82k
    *result = frame->env[entry->value];
59
2.82k
    if (kind == MVM_reg_obj && !result->o)
60
1.18k
        result->o = MVM_frame_vivify_lexical(tc, frame, entry->value);
61
2.82k
}
62
63
6
static void bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister value, MVMuint16 kind) {
64
6
    MVMString      *name  = (MVMString *)key;
65
6
    MVMContextBody *body  = (MVMContextBody *)data;
66
6
    MVMFrame       *frame = body->context;
67
6
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
68
6
    MVMuint16 got_kind;
69
6
70
6
    if (!lexical_names) {
71
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
72
0
        char *waste[] = { c_name, NULL };
73
0
        MVM_exception_throw_adhoc_free(tc, waste,
74
0
            "Lexical with name '%s' does not exist in this frame",
75
0
                c_name);
76
0
    }
77
6
78
6
    MVM_HASH_GET(tc, lexical_names, name, entry);
79
6
    if (!entry) {
80
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
81
0
        char *waste[] = { c_name, NULL };
82
0
        MVM_exception_throw_adhoc_free(tc, waste,
83
0
            "Lexical with name '%s' does not exist in this frame",
84
0
                c_name);
85
0
    }
86
6
87
6
    got_kind = frame->static_info->body.lexical_types[entry->value];
88
6
    if (got_kind != kind) {
89
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
90
0
        char *waste[] = { c_name, NULL };
91
0
        MVM_exception_throw_adhoc_free(tc, waste,
92
0
            "Lexical with name '%s' has a different type in this frame",
93
0
                c_name);
94
0
    }
95
6
96
6
    if (got_kind == MVM_reg_obj || got_kind == MVM_reg_str) {
97
4
        MVM_ASSIGN_REF(tc, &(frame->header), frame->env[entry->value].o, value.o);
98
4
    }
99
2
    else {
100
2
        frame->env[entry->value] = value;
101
2
    }
102
6
}
103
104
0
static MVMuint64 elems(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
105
0
    MVMContextBody *body  = (MVMContextBody *)data;
106
0
    MVMFrame       *frame = body->context;
107
0
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names;
108
0
    return (MVMuint64) HASH_CNT(hash_handle, lexical_names);
109
0
}
110
111
168
static MVMint64 exists_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
112
168
    MVMContextBody *body = (MVMContextBody *)data;
113
168
    MVMFrame *frame = body->context;
114
168
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
115
168
    MVMString *name = (MVMString *)key;
116
168
    if (!lexical_names)
117
0
        return 0;
118
168
    MVM_HASH_GET(tc, lexical_names, name, entry);
119
149
    return entry ? 1 : 0;
120
168
}
121
122
0
static void delete_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
123
0
    MVM_exception_throw_adhoc(tc,
124
0
        "MVMContext representation does not support delete key");
125
0
}
126
127
0
static MVMStorageSpec get_value_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
128
0
    MVMStorageSpec spec;
129
0
    spec.inlineable      = MVM_STORAGE_SPEC_REFERENCE;
130
0
    spec.boxed_primitive = MVM_STORAGE_SPEC_BP_NONE;
131
0
    spec.can_box         = 0;
132
0
    spec.bits            = 0;
133
0
    spec.align           = 0;
134
0
    spec.is_unsigned     = 0;
135
0
136
0
    return spec;
137
0
}
138
139
static const MVMStorageSpec storage_spec = {
140
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
141
    0,                          /* bits */
142
    0,                          /* align */
143
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
144
    0,                          /* can_box */
145
    0,                          /* is_unsigned */
146
};
147
148
149
/* Gets the storage specification for this representation. */
150
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
151
0
    return &storage_spec;
152
0
}
153
154
/* Compose the representation. */
155
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
156
0
    /* Nothing to do for this REPR. */
157
0
}
158
159
/* Initializes the representation. */
160
130
const MVMREPROps * MVMContext_initialize(MVMThreadContext *tc) {
161
130
    return &MVMContext_this_repr;
162
130
}
163
164
static const MVMREPROps MVMContext_this_repr = {
165
    type_object_for,
166
    MVM_gc_allocate_object,
167
    NULL, /* initialize */
168
    copy_to,
169
    MVM_REPR_DEFAULT_ATTR_FUNCS,
170
    MVM_REPR_DEFAULT_BOX_FUNCS,
171
    MVM_REPR_DEFAULT_POS_FUNCS,
172
    {
173
        at_key,
174
        bind_key,
175
        exists_key,
176
        delete_key,
177
        get_value_storage_spec
178
    },   /* ass_funcs */
179
    elems,
180
    get_storage_spec,
181
    NULL, /* change_type */
182
    NULL, /* serialize */
183
    NULL, /* deserialize */
184
    NULL, /* serialize_repr_data */
185
    NULL, /* deserialize_repr_data */
186
    NULL, /* deserialize_stable_size */
187
    gc_mark,
188
    NULL, /* gc_free */
189
    NULL, /* gc_cleanup */
190
    NULL, /* gc_mark_repr_data */
191
    NULL, /* gc_free_repr_data */
192
    compose,
193
    NULL, /* spesh */
194
    "MVMContext", /* name */
195
    MVM_REPR_ID_MVMContext,
196
    NULL, /* unmanaged_size */
197
    NULL, /* describe_refs */
198
};