Coverage Report

Created: 2017-04-15 07:07

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/P6int.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
#ifdef MVM_BOOL
3
#include <stdbool.h>
4
#endif
5
6
/* This representation's function pointer table. */
7
static const MVMREPROps P6int_this_repr;
8
9
1.44k
static void mk_storage_spec(MVMThreadContext *tc, MVMuint16 bits, MVMuint16 is_unsigned, MVMStorageSpec *spec) {
10
1.44k
    /* create storage spec */
11
1.44k
    spec->inlineable      = MVM_STORAGE_SPEC_INLINED;
12
1.44k
    spec->boxed_primitive = MVM_STORAGE_SPEC_BP_INT;
13
1.44k
    spec->can_box         = MVM_STORAGE_SPEC_CAN_BOX_INT;
14
1.44k
    spec->bits            = bits;
15
1.44k
    spec->is_unsigned     = is_unsigned;
16
1.44k
    switch (bits) {
17
661
    case 64: spec->align = ALIGNOF(MVMint64); break;
18
260
    case 32: spec->align = ALIGNOF(MVMint32); break;
19
260
    case 16: spec->align = ALIGNOF(MVMint16); break;
20
260
    default: spec->align = ALIGNOF(MVMint8);  break;
21
1.44k
    }
22
1.44k
}
23
24
25
/* Creates a new type object of this representation, and associates it with
26
 * the given HOW. */
27
135
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
28
135
    MVMSTable *st  = MVM_gc_allocate_stable(tc, &P6int_this_repr, HOW);
29
135
30
135
    MVMROOT(tc, st, {
31
135
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
32
135
        MVMP6intREPRData *repr_data = (MVMP6intREPRData *)MVM_malloc(sizeof(MVMP6intREPRData));
33
135
34
135
        repr_data->bits = sizeof(MVMint64) * 8;
35
135
        repr_data->is_unsigned = 0;
36
135
        mk_storage_spec(tc, repr_data->bits, repr_data->is_unsigned, &repr_data->storage_spec);
37
135
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
38
135
        st->size = sizeof(MVMP6int);
39
135
        st->REPR_data = repr_data;
40
135
41
135
    });
42
135
43
135
    return st->WHAT;
44
135
}
45
46
/* Copies the body of one object to another. */
47
736
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
48
736
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
49
736
    MVMP6intBody *src_body  = (MVMP6intBody *)src;
50
736
    MVMP6intBody *dest_body = (MVMP6intBody *)dest;
51
736
    switch (repr_data->bits) {
52
736
        case 64: dest_body->value.i64 = src_body->value.i64; break;
53
0
        case 32: dest_body->value.i32 = src_body->value.i32; break;
54
0
        case 16: dest_body->value.i16 = src_body->value.i16; break;
55
0
        default: dest_body->value.i8 = src_body->value.i8; break;
56
736
    }
57
736
}
58
59
0
static void set_uint(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMuint64 value) {
60
0
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
61
0
    switch (repr_data->bits) {
62
0
        case 64: ((MVMP6intBody *)data)->value.u64 = value; break;
63
0
        case 32: ((MVMP6intBody *)data)->value.u32 = (MVMuint32)value; break;
64
0
        case 16: ((MVMP6intBody *)data)->value.u16 = (MVMuint16)value; break;
65
0
        default: ((MVMP6intBody *)data)->value.u8 = (MVMuint8)value; break;
66
0
    }
67
0
}
68
69
0
static MVMuint64 get_uint(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
70
0
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
71
0
    switch (repr_data->bits) {
72
0
        case 64: return ((MVMP6intBody *)data)->value.u64;
73
0
        case 32: return ((MVMP6intBody *)data)->value.u32;
74
0
        case 16: return ((MVMP6intBody *)data)->value.u16;
75
0
        default: return ((MVMP6intBody *)data)->value.u8;
76
0
    }
77
0
}
78
79
4.01M
static void set_int(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 value) {
80
4.01M
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
81
4.01M
    switch (repr_data->bits) {
82
4.01M
        case 64: ((MVMP6intBody *)data)->value.i64 = value; break;
83
0
        case 32: ((MVMP6intBody *)data)->value.i32 = (MVMint32)value; break;
84
0
        case 16: ((MVMP6intBody *)data)->value.i16 = (MVMint16)value; break;
85
0
        default: ((MVMP6intBody *)data)->value.i8 = (MVMint8)value; break;
86
4.01M
    }
87
4.01M
}
88
89
15.2M
static MVMint64 get_int(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
90
15.2M
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
91
15.2M
    switch (repr_data->bits) {
92
15.2M
        case 64: return ((MVMP6intBody *)data)->value.i64;
93
0
        case 32: return ((MVMP6intBody *)data)->value.i32;
94
0
        case 16: return ((MVMP6intBody *)data)->value.i16;
95
0
        default: return ((MVMP6intBody *)data)->value.i8;
96
15.2M
    }
97
15.2M
}
98
99
/* Marks the representation data in an STable.*/
100
0
static void gc_free_repr_data(MVMThreadContext *tc, MVMSTable *st) {
101
0
    MVM_free(st->REPR_data);
102
0
}
103
104
static const MVMStorageSpec default_storage_spec = {
105
    MVM_STORAGE_SPEC_INLINED,     /* inlineable */
106
    sizeof(MVMint64) * 8,         /* bits */
107
    ALIGNOF(MVMint64),            /* align */
108
    MVM_STORAGE_SPEC_BP_INT,      /* boxed_primitive */
109
    MVM_STORAGE_SPEC_CAN_BOX_INT, /* can_box */
110
    0,                            /* is_unsigned */
111
};
112
113
114
/* Gets the storage specification for this representation. */
115
3.82M
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
116
3.82M
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
117
3.82M
    if (repr_data && repr_data->bits)
118
3.82M
        return &repr_data->storage_spec;
119
260
    return &default_storage_spec;
120
3.82M
}
121
122
/* Compose the representation. */
123
5
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info_hash) {
124
5
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
125
5
    MVMStringConsts  str_consts = tc->instance->str_consts;
126
5
127
5
    MVMObject *info = MVM_repr_at_key_o(tc, info_hash, str_consts.integer);
128
5
    if (!MVM_is_null(tc, info)) {
129
0
        MVMObject *bits_o        = MVM_repr_at_key_o(tc, info, str_consts.bits);
130
0
        MVMObject *is_unsigned_o = MVM_repr_at_key_o(tc, info, str_consts.unsigned_str);
131
0
132
0
        if (!MVM_is_null(tc, bits_o)) {
133
0
            repr_data->bits = MVM_repr_get_int(tc, bits_o);
134
0
135
0
            switch (repr_data->bits) {
136
0
                case MVM_P6INT_C_TYPE_CHAR:     repr_data->bits = 8 * sizeof(char);      break;
137
0
                case MVM_P6INT_C_TYPE_SHORT:    repr_data->bits = 8 * sizeof(short);     break;
138
0
                case MVM_P6INT_C_TYPE_INT:      repr_data->bits = 8 * sizeof(int);       break;
139
0
                case MVM_P6INT_C_TYPE_LONG:     repr_data->bits = 8 * sizeof(long);      break;
140
0
                case MVM_P6INT_C_TYPE_LONGLONG: repr_data->bits = 8 * sizeof(long long); break;
141
0
                case MVM_P6INT_C_TYPE_SIZE_T:   repr_data->bits = 8 * sizeof(size_t);    break;
142
0
#ifdef MVM_BOOL
143
0
                case MVM_P6INT_C_TYPE_BOOL:     repr_data->bits = 8 * sizeof(MVM_BOOL);  break;
144
0
#else
145
                case MVM_P6INT_C_TYPE_BOOL:     repr_data->bits = 8 * sizeof(char);      break;
146
#endif
147
0
            }
148
0
149
0
            if (repr_data->bits !=  1 && repr_data->bits !=  2 && repr_data->bits !=  4 && repr_data->bits != 8
150
0
             && repr_data->bits != 16 && repr_data->bits != 32 && repr_data->bits != 64)
151
0
                MVM_exception_throw_adhoc(tc, "MVMP6int: Unsupported int size (%dbit)", repr_data->bits);
152
0
        } else {
153
0
            repr_data->bits = default_storage_spec.bits;
154
0
        }
155
0
156
0
        if (!MVM_is_null(tc, is_unsigned_o)) {
157
0
            repr_data->is_unsigned = MVM_repr_get_int(tc, is_unsigned_o);
158
0
        }
159
0
    }
160
5
    if (repr_data->bits)
161
5
        mk_storage_spec(tc, repr_data->bits, repr_data->is_unsigned, &repr_data->storage_spec);
162
5
}
163
164
/* Set the size of the STable. */
165
1.30k
static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
166
1.30k
    st->size = sizeof(MVMP6int);
167
1.30k
}
168
169
/* Serializes the REPR data. */
170
1
static void serialize_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMSerializationWriter *writer) {
171
1
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)st->REPR_data;
172
1
    MVM_serialization_write_int(tc, writer, repr_data->bits);
173
1
    MVM_serialization_write_int(tc, writer, repr_data->is_unsigned);
174
1
}
175
176
/* Deserializes representation data. */
177
1.30k
static void deserialize_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
178
1.30k
    MVMP6intREPRData *repr_data = (MVMP6intREPRData *)MVM_malloc(sizeof(MVMP6intREPRData));
179
1.30k
180
1.30k
181
1.30k
    repr_data->bits        = MVM_serialization_read_int(tc, reader);
182
1.30k
    repr_data->is_unsigned = MVM_serialization_read_int(tc, reader);
183
1.30k
184
1.30k
    if (repr_data->bits !=  1 && repr_data->bits !=  2 && repr_data->bits !=  4 && repr_data->bits != 8
185
1.04k
     && repr_data->bits != 16 && repr_data->bits != 32 && repr_data->bits != 64)
186
0
        MVM_exception_throw_adhoc(tc, "MVMP6int: Unsupported int size (%dbit)", repr_data->bits);
187
1.30k
188
1.30k
    mk_storage_spec(tc, repr_data->bits, repr_data->is_unsigned, &repr_data->storage_spec);
189
1.30k
190
1.30k
    st->REPR_data = repr_data;
191
1.30k
}
192
193
137k
static void deserialize(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMSerializationReader *reader) {
194
137k
    set_int(tc, st, root, data, MVM_serialization_read_int(tc, reader));
195
137k
}
196
197
18
static void serialize(MVMThreadContext *tc, MVMSTable *st, void *data, MVMSerializationWriter *writer) {
198
18
    MVM_serialization_write_int(tc, writer, get_int(tc, st, NULL, data));
199
18
}
200
201
/* Initializes the representation. */
202
130
const MVMREPROps * MVMP6int_initialize(MVMThreadContext *tc) {
203
130
    return &P6int_this_repr;
204
130
}
205
206
static const MVMREPROps P6int_this_repr = {
207
    type_object_for,
208
    MVM_gc_allocate_object,
209
    NULL, /* initialize */
210
    copy_to,
211
    MVM_REPR_DEFAULT_ATTR_FUNCS,
212
    {
213
        set_int,
214
        get_int,
215
        MVM_REPR_DEFAULT_SET_NUM,
216
        MVM_REPR_DEFAULT_GET_NUM,
217
        MVM_REPR_DEFAULT_SET_STR,
218
        MVM_REPR_DEFAULT_GET_STR,
219
        set_uint,
220
        get_uint,
221
        MVM_REPR_DEFAULT_GET_BOXED_REF
222
    },    /* box_funcs */
223
    MVM_REPR_DEFAULT_POS_FUNCS,
224
    MVM_REPR_DEFAULT_ASS_FUNCS,
225
    MVM_REPR_DEFAULT_ELEMS,
226
    get_storage_spec,
227
    NULL, /* change_type */
228
    serialize,
229
    deserialize,
230
    serialize_repr_data,
231
    deserialize_repr_data,
232
    deserialize_stable_size,
233
    NULL, /* gc_mark */
234
    NULL, /* gc_free */
235
    NULL, /* gc_cleanup */
236
    NULL, /* gc_mark_repr_data */
237
    gc_free_repr_data,
238
    compose,
239
    NULL, /* spesh */
240
    "P6int", /* name */
241
    MVM_REPR_ID_P6int,
242
    NULL, /* unmanaged_size */
243
    NULL, /* describe_refs */
244
};