Coverage Report

Created: 2018-07-03 15:31

/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
144
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
144
    MVMSTable *st = MVM_gc_allocate_stable(tc, &MVMContext_this_repr, HOW);
10
144
11
144
    MVMROOT(tc, st, {
12
144
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
144
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
144
        st->size = sizeof(MVMContext);
15
144
    });
16
144
17
144
    return st->WHAT;
18
144
}
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
795
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
27
795
    MVMContextBody *body = (MVMContextBody *)data;
28
795
    MVM_gc_worklist_add(tc, worklist, &body->context);
29
795
}
30
31
3.15k
static void at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister *result, MVMuint16 kind) {
32
3.15k
    MVMString      *name  = (MVMString *)key;
33
3.15k
    MVMContextBody *body  = (MVMContextBody *)data;
34
3.15k
    MVMFrame       *frame = body->context;
35
3.15k
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
36
3.15k
    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
3.15k
    MVM_HASH_GET(tc, lexical_names, name, entry);
44
3.15k
    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
3.15k
    if (frame->static_info->body.lexical_types[entry->value] != kind) {
52
0
        if (kind == MVM_reg_int64) {
53
0
            switch (frame->static_info->body.lexical_types[entry->value]) {
54
0
                case MVM_reg_int8:
55
0
                    result->i64 = frame->env[entry->value].i8;
56
0
                    return;
57
0
                case MVM_reg_int16:
58
0
                    result->i64 = frame->env[entry->value].i16;
59
0
                    return;
60
0
                case MVM_reg_int32:
61
0
                    result->i64 = frame->env[entry->value].i32;
62
0
                    return;
63
0
            }
64
0
        }
65
0
        else if (kind == MVM_reg_uint64) {
66
0
            switch (frame->static_info->body.lexical_types[entry->value]) {
67
0
                case MVM_reg_uint8:
68
0
                    result->u64 = frame->env[entry->value].u8;
69
0
                    return;
70
0
                case MVM_reg_uint16:
71
0
                    result->u64 = frame->env[entry->value].u16;
72
0
                    return;
73
0
                case MVM_reg_uint32:
74
0
                    result->u64 = frame->env[entry->value].u32;
75
0
                    return;
76
0
                case MVM_reg_uint64:
77
0
                    result->u64 = frame->env[entry->value].u64;
78
0
                    return;
79
0
            }
80
0
81
0
        }
82
0
        {
83
0
            char *c_name = MVM_string_utf8_encode_C_string(tc, name);
84
0
            char *waste[] = { c_name, NULL };
85
0
            MVM_exception_throw_adhoc_free(tc, waste,
86
0
                "Lexical with name '%s' has a different type in this frame",
87
0
                    c_name);
88
0
        }
89
0
    }
90
3.15k
    *result = frame->env[entry->value];
91
3.15k
    if (kind == MVM_reg_obj && !result->o)
92
1.31k
        result->o = MVM_frame_vivify_lexical(tc, frame, entry->value);
93
3.15k
}
94
95
8
static void bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister value, MVMuint16 kind) {
96
8
    MVMString      *name  = (MVMString *)key;
97
8
    MVMContextBody *body  = (MVMContextBody *)data;
98
8
    MVMFrame       *frame = body->context;
99
8
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
100
8
    MVMuint16 got_kind;
101
8
102
8
    if (!lexical_names) {
103
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
104
0
        char *waste[] = { c_name, NULL };
105
0
        MVM_exception_throw_adhoc_free(tc, waste,
106
0
            "Lexical with name '%s' does not exist in this frame",
107
0
                c_name);
108
0
    }
109
8
110
8
    MVM_HASH_GET(tc, lexical_names, name, entry);
111
8
    if (!entry) {
112
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
113
0
        char *waste[] = { c_name, NULL };
114
0
        MVM_exception_throw_adhoc_free(tc, waste,
115
0
            "Lexical with name '%s' does not exist in this frame",
116
0
                c_name);
117
0
    }
118
8
119
8
    got_kind = frame->static_info->body.lexical_types[entry->value];
120
8
    if (got_kind != kind) {
121
0
        char *c_name = MVM_string_utf8_encode_C_string(tc, name);
122
0
        char *waste[] = { c_name, NULL };
123
0
        MVM_exception_throw_adhoc_free(tc, waste,
124
0
            "Lexical with name '%s' has a different type in this frame",
125
0
                c_name);
126
0
    }
127
8
128
8
    if (got_kind == MVM_reg_obj || got_kind == MVM_reg_str) {
129
6
        MVM_ASSIGN_REF(tc, &(frame->header), frame->env[entry->value].o, value.o);
130
6
    }
131
2
    else {
132
2
        frame->env[entry->value] = value;
133
2
    }
134
8
}
135
136
1
static MVMuint64 elems(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
137
1
    MVMContextBody *body  = (MVMContextBody *)data;
138
1
    MVMFrame       *frame = body->context;
139
1
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names;
140
1
    return (MVMuint64) HASH_CNT(hash_handle, lexical_names);
141
1
}
142
143
187
static MVMint64 exists_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
144
187
    MVMContextBody *body = (MVMContextBody *)data;
145
187
    MVMFrame *frame = body->context;
146
187
    MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
147
187
    MVMString *name = (MVMString *)key;
148
187
    if (!lexical_names)
149
0
        return 0;
150
187
    MVM_HASH_GET(tc, lexical_names, name, entry);
151
166
    return entry ? 1 : 0;
152
187
}
153
154
0
static void delete_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
155
0
    MVM_exception_throw_adhoc(tc,
156
0
        "MVMContext representation does not support delete key");
157
0
}
158
159
0
static MVMStorageSpec get_value_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
160
0
    MVMStorageSpec spec;
161
0
    spec.inlineable      = MVM_STORAGE_SPEC_REFERENCE;
162
0
    spec.boxed_primitive = MVM_STORAGE_SPEC_BP_NONE;
163
0
    spec.can_box         = 0;
164
0
    spec.bits            = 0;
165
0
    spec.align           = 0;
166
0
    spec.is_unsigned     = 0;
167
0
168
0
    return spec;
169
0
}
170
171
static const MVMStorageSpec storage_spec = {
172
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
173
    0,                          /* bits */
174
    0,                          /* align */
175
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
176
    0,                          /* can_box */
177
    0,                          /* is_unsigned */
178
};
179
180
181
/* Gets the storage specification for this representation. */
182
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
183
0
    return &storage_spec;
184
0
}
185
186
/* Compose the representation. */
187
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
188
0
    /* Nothing to do for this REPR. */
189
0
}
190
191
/* Initializes the representation. */
192
144
const MVMREPROps * MVMContext_initialize(MVMThreadContext *tc) {
193
144
    return &MVMContext_this_repr;
194
144
}
195
196
static const MVMREPROps MVMContext_this_repr = {
197
    type_object_for,
198
    MVM_gc_allocate_object,
199
    NULL, /* initialize */
200
    copy_to,
201
    MVM_REPR_DEFAULT_ATTR_FUNCS,
202
    MVM_REPR_DEFAULT_BOX_FUNCS,
203
    MVM_REPR_DEFAULT_POS_FUNCS,
204
    {
205
        at_key,
206
        bind_key,
207
        exists_key,
208
        delete_key,
209
        get_value_storage_spec
210
    },   /* ass_funcs */
211
    elems,
212
    get_storage_spec,
213
    NULL, /* change_type */
214
    NULL, /* serialize */
215
    NULL, /* deserialize */
216
    NULL, /* serialize_repr_data */
217
    NULL, /* deserialize_repr_data */
218
    NULL, /* deserialize_stable_size */
219
    gc_mark,
220
    NULL, /* gc_free */
221
    NULL, /* gc_cleanup */
222
    NULL, /* gc_mark_repr_data */
223
    NULL, /* gc_free_repr_data */
224
    compose,
225
    NULL, /* spesh */
226
    "MVMContext", /* name */
227
    MVM_REPR_ID_MVMContext,
228
    NULL, /* unmanaged_size */
229
    NULL, /* describe_refs */
230
};