Coverage Report

Created: 2018-06-21 18:56

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/CArray.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 CArray_this_repr;
5
6
/* Creates a new type object of this representation, and associates it with
7
 * the given HOW. */
8
0
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
0
    MVMSTable *st = MVM_gc_allocate_stable(tc, &CArray_this_repr, HOW);
10
0
11
0
    MVMROOT(tc, st, {
12
0
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
0
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
0
        st->size = sizeof(MVMCArray);
15
0
    });
16
0
17
0
    return st->WHAT;
18
0
}
19
20
/* Composes the representation. */
21
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info_hash) {
22
0
    MVMStringConsts str_consts = tc->instance->str_consts;
23
0
    MVMObject *info = MVM_repr_at_key_o(tc, info_hash, str_consts.array);
24
0
    if (!MVM_is_null(tc, info)) {
25
0
        MVMCArrayREPRData *repr_data = MVM_malloc(sizeof(MVMCArrayREPRData));
26
0
        MVMObject *type    = MVM_repr_at_key_o(tc, info, str_consts.type);
27
0
        const MVMStorageSpec *ss = REPR(type)->get_storage_spec(tc, STABLE(type));
28
0
        MVMint32 type_id   = REPR(type)->ID;
29
0
30
0
        MVM_ASSIGN_REF(tc, &(st->header), repr_data->elem_type, type);
31
0
        st->REPR_data = repr_data;
32
0
33
0
        if (ss->boxed_primitive == MVM_STORAGE_SPEC_BP_INT) {
34
0
            if (ss->bits == 8 || ss->bits == 16 || ss->bits == 32 || ss->bits == 64)
35
0
                repr_data->elem_size = ss->bits / 8;
36
0
            else
37
0
                MVM_exception_throw_adhoc(tc,
38
0
                    "CArray representation can only have 8, 16, 32 or 64 bit integer elements");
39
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_NUMERIC;
40
0
        }
41
0
        else if (ss->boxed_primitive == MVM_STORAGE_SPEC_BP_NUM) {
42
0
            if (ss->bits == 32 || ss->bits == 64)
43
0
                repr_data->elem_size = ss->bits / 8;
44
0
            else
45
0
                MVM_exception_throw_adhoc(tc,
46
0
                    "CArray representation can only have 32 or 64 bit floating point elements");
47
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_NUMERIC;
48
0
        }
49
0
        else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_STR) {
50
0
            repr_data->elem_size = sizeof(MVMObject *);
51
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_STRING;
52
0
        }
53
0
        else if (type_id == MVM_REPR_ID_MVMCArray) {
54
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_CARRAY;
55
0
            repr_data->elem_size = sizeof(void *);
56
0
        }
57
0
        else if (type_id == MVM_REPR_ID_MVMCStruct) {
58
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_CSTRUCT;
59
0
            repr_data->elem_size = sizeof(void *);
60
0
        }
61
0
        else if (type_id == MVM_REPR_ID_MVMCPPStruct) {
62
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_CPPSTRUCT;
63
0
            repr_data->elem_size = sizeof(void *);
64
0
        }
65
0
        else if (type_id == MVM_REPR_ID_MVMCUnion) {
66
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_CUNION;
67
0
            repr_data->elem_size = sizeof(void *);
68
0
        }
69
0
        else if (type_id == MVM_REPR_ID_MVMCPointer) {
70
0
            repr_data->elem_kind = MVM_CARRAY_ELEM_KIND_CPOINTER;
71
0
            repr_data->elem_size = sizeof(void *);
72
0
        }
73
0
        else {
74
0
            MVM_exception_throw_adhoc(tc,
75
0
                "CArray representation only handles attributes of type:\n"
76
0
                "  (u)int8, (u)int16, (u)int32, (u)int64, (u)long, (u)longlong, num32, num64, (s)size_t, bool, Str\n"
77
0
                "  and types with representation: CArray, CPointer, CStruct, CPPStruct and CUnion");
78
0
        }
79
0
    }
80
0
    else {
81
0
        MVM_exception_throw_adhoc(tc, "CArray representation requires a typed array");
82
0
    }
83
0
}
84
85
/* Initialize a new instance. */
86
0
static void initialize(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
87
0
    /* If we're initialized, presumably we're going to be
88
0
     * managing the memory in this array ourself. */
89
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
90
0
    MVMCArrayBody     *body      = (MVMCArrayBody *)data;
91
0
92
0
    if (!repr_data)
93
0
        MVM_exception_throw_adhoc(tc, "CArray type must be composed before use");
94
0
95
0
    body->storage = MVM_calloc(4, repr_data->elem_size);
96
0
    body->managed = 1;
97
0
98
0
    /* Don't need child_objs for numerics. */
99
0
    if (repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_NUMERIC)
100
0
        body->child_objs = NULL;
101
0
    else
102
0
        body->child_objs = (MVMObject **) MVM_calloc(4, sizeof(MVMObject *));
103
0
104
0
    body->allocated = 4;
105
0
    body->elems = 0;
106
0
}
107
108
/* Copies to the body of one object to another. */
109
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
110
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
111
0
    MVMCArrayBody     *src_body  = (MVMCArrayBody *)src;
112
0
    MVMCArrayBody     *dest_body = (MVMCArrayBody *)dest;
113
0
114
0
    if (src_body->managed) {
115
0
        MVMint32 alsize = src_body->allocated * repr_data->elem_size;
116
0
        dest_body->storage = MVM_malloc(alsize);
117
0
        memcpy(dest_body->storage, src_body->storage, alsize);
118
0
    }
119
0
    else {
120
0
        dest_body->storage = src_body->storage;
121
0
    }
122
0
    dest_body->managed = src_body->managed;
123
0
    dest_body->allocated = src_body->allocated;
124
0
    dest_body->elems = src_body->elems;
125
0
}
126
127
/* This is called to do any cleanup of resources when an object gets
128
 * embedded inside another one. Never called on a top-level object. */
129
0
static void gc_cleanup(MVMThreadContext *tc, MVMSTable *st, void *data) {
130
0
    MVMCArrayBody *body = (MVMCArrayBody *)data;
131
0
132
0
    if (body->managed) 
133
0
        MVM_free(body->storage);
134
0
    if (body->child_objs)
135
0
        MVM_free(body->child_objs);
136
0
}
137
138
0
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
139
0
    gc_cleanup(tc, STABLE(obj), OBJECT_BODY(obj));
140
0
}
141
142
0
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
143
0
    MVMCArrayBody *body = (MVMCArrayBody *)data;
144
0
    const MVMint32 elems = body->elems;
145
0
    MVMint32 i;
146
0
147
0
    /* Don't traverse child_objs list if there isn't one. */
148
0
    if (!body->child_objs) return;
149
0
150
0
    for (i = 0; i < elems; i++)
151
0
        if (body->child_objs[i])
152
0
            MVM_gc_worklist_add(tc, worklist, &body->child_objs[i]);
153
0
}
154
155
/* Marks the representation data in an STable.*/
156
0
static void gc_mark_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMGCWorklist *worklist) {
157
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
158
0
    if (repr_data)
159
0
        MVM_gc_worklist_add(tc, worklist, &repr_data->elem_type);
160
0
}
161
162
/* Free representation data. */
163
0
static void gc_free_repr_data(MVMThreadContext *tc, MVMSTable *st) {
164
0
    MVM_free(st->REPR_data);
165
0
}
166
167
static const MVMStorageSpec storage_spec = {
168
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
169
    sizeof(void *) * 8,         /* bits */
170
    ALIGNOF(void *),            /* align */
171
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
172
    0,                          /* can_box */
173
    0,                          /* is_unsigned */
174
};
175
176
177
/* Gets the storage specification for this representation. */
178
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
179
0
    return &storage_spec;
180
0
}
181
182
183
MVM_NO_RETURN static void die_pos_nyi(MVMThreadContext *tc) MVM_NO_RETURN_ATTRIBUTE;
184
0
static void die_pos_nyi(MVMThreadContext *tc) {
185
0
    MVM_exception_throw_adhoc(tc,
186
0
        "CArray representation does not fully positional storage yet");
187
0
}
188
189
190
0
static void expand(MVMThreadContext *tc, MVMCArrayREPRData *repr_data, MVMCArrayBody *body, MVMint32 min_size) {
191
0
    MVMint8 is_complex;
192
0
    MVMint32 next_size = body->allocated? 2 * body->allocated: 4;
193
0
194
0
    if (min_size > next_size)
195
0
        next_size = min_size;
196
0
197
0
    if (body->managed) {
198
0
        const size_t old_size = body->allocated * repr_data->elem_size;
199
0
        const size_t new_size = next_size * repr_data->elem_size;
200
0
201
0
        body->storage = MVM_realloc(body->storage, new_size);
202
0
        memset((char *)body->storage + old_size, 0, new_size - old_size);
203
0
    }
204
0
205
0
    is_complex = (repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_CARRAY
206
0
               || repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_CPOINTER
207
0
               || repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_CSTRUCT
208
0
               || repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_CPPSTRUCT
209
0
               || repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_CUNION
210
0
               || repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_STRING);
211
0
212
0
    if (is_complex) {
213
0
        const size_t old_size = body->allocated * sizeof(MVMObject *);
214
0
        const size_t new_size = next_size * sizeof(MVMObject *);
215
0
216
0
        body->child_objs = (MVMObject **) MVM_realloc(body->child_objs, new_size);
217
0
        memset((char *)body->child_objs + old_size, 0, new_size - old_size);
218
0
    }
219
0
220
0
    body->allocated = next_size;
221
0
}
222
223
0
static MVMObject * make_wrapper(MVMThreadContext *tc, MVMSTable *st, void *data) {
224
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
225
0
    switch (repr_data->elem_kind) {
226
0
        case MVM_CARRAY_ELEM_KIND_STRING: {
227
0
            MVMString *str = MVM_string_utf8_decode(tc, tc->instance->VMString,
228
0
                (char *)data, strlen((char *)data));
229
0
            return MVM_repr_box_str(tc, repr_data->elem_type, str);
230
0
        }
231
0
        case MVM_CARRAY_ELEM_KIND_CPOINTER:
232
0
            return MVM_nativecall_make_cpointer(tc, repr_data->elem_type, data);
233
0
        case MVM_CARRAY_ELEM_KIND_CARRAY:
234
0
            return MVM_nativecall_make_carray(tc, repr_data->elem_type, data);
235
0
        case MVM_CARRAY_ELEM_KIND_CSTRUCT:
236
0
            return MVM_nativecall_make_cstruct(tc, repr_data->elem_type, data);
237
0
        default:
238
0
            MVM_exception_throw_adhoc(tc, "Unknown element type in CArray");
239
0
    }
240
0
}
241
0
static void at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind) {
242
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
243
0
    MVMCArrayBody     *body      = (MVMCArrayBody *)data;
244
0
    void              *ptr       = ((char *)body->storage) + index * repr_data->elem_size;
245
0
    switch (repr_data->elem_kind) {
246
0
        case MVM_CARRAY_ELEM_KIND_NUMERIC:
247
0
            if (kind == MVM_reg_int64)
248
0
                value->i64 = body->managed && index >= body->elems
249
0
                    ? 0
250
0
                    : REPR(repr_data->elem_type)->box_funcs.get_int(tc,
251
0
                        STABLE(repr_data->elem_type), root, ptr);
252
0
            else if (kind == MVM_reg_num64)
253
0
                value->n64 = body->managed && index >= body->elems
254
0
                    ? 0.0
255
0
                    : REPR(repr_data->elem_type)->box_funcs.get_num(tc,
256
0
                        STABLE(repr_data->elem_type), root, ptr);
257
0
            else
258
0
                MVM_exception_throw_adhoc(tc, "Wrong kind of access to numeric CArray");
259
0
            break;
260
0
        case MVM_CARRAY_ELEM_KIND_STRING:
261
0
        case MVM_CARRAY_ELEM_KIND_CPOINTER:
262
0
        case MVM_CARRAY_ELEM_KIND_CARRAY:
263
0
        case MVM_CARRAY_ELEM_KIND_CSTRUCT: {
264
0
            if (kind != MVM_reg_obj)
265
0
                MVM_exception_throw_adhoc(tc, "Wrong kind of access to object CArray");
266
0
            if (body->managed) {
267
0
                /* We manage this array. If we're out of range, just use type object. */
268
0
                if (index >= body->elems) {
269
0
                    value->o = repr_data->elem_type;
270
0
                }
271
0
272
0
                /* Otherwise we may have a cached object result. */
273
0
                else if (body->child_objs[index]) {
274
0
                    value->o = body->child_objs[index];
275
0
                }
276
0
277
0
                /* If not, we need to produce and cache it. */
278
0
                else {
279
0
                    void **storage = (void **)body->storage;
280
0
                    MVMROOT(tc, root, {
281
0
                        MVMObject **child_objs = body->child_objs;
282
0
                        MVMObject *wrapped = make_wrapper(tc, st, storage[index]);
283
0
                        MVM_ASSIGN_REF(tc, &(root->header), child_objs[index], wrapped);
284
0
                        value->o = wrapped;
285
0
                    });
286
0
                }
287
0
            }
288
0
            else {
289
0
                void **storage;
290
0
291
0
                /* Array comes from C. Enlarge child_objs if needed. */
292
0
                if (index >= body->allocated)
293
0
                    expand(tc, repr_data, body, index + 1);
294
0
                if (index >= body->elems)
295
0
                    body->elems = index + 1;
296
0
297
0
                storage = (void **)body->storage;
298
0
299
0
                /* We've already fetched this object; use cached one. */
300
0
                if (storage[index] && body->child_objs[index]) {
301
0
                    value->o = body->child_objs[index];
302
0
                }
303
0
304
0
                /* No cached object, but non-NULL pointer in array. Construct object,
305
0
                 * put it in the cache and return it. */
306
0
                else if (storage[index]) {
307
0
                    MVMROOT(tc, root, {
308
0
                        MVMObject **child_objs = body->child_objs;
309
0
                        MVMObject *wrapped = make_wrapper(tc, st, storage[index]);
310
0
                        MVM_ASSIGN_REF(tc, &(root->header), child_objs[index], wrapped);
311
0
                        value->o = wrapped;
312
0
                    });
313
0
                }
314
0
315
0
                /* NULL pointer in the array; result is the type object. */
316
0
                else {
317
0
                    value->o = repr_data->elem_type;
318
0
                }
319
0
            }
320
0
            break;
321
0
        }
322
0
        default:
323
0
            MVM_exception_throw_adhoc(tc, "Unknown element type in CArray");
324
0
    }
325
0
}
326
327
static void bind_wrapper_and_ptr(MVMThreadContext *tc, MVMObject *root, MVMCArrayBody *body,
328
0
        MVMint64 index, MVMObject *wrapper, void *cptr) {
329
0
    if (index >= body->allocated)
330
0
        expand(tc, STABLE(root)->REPR_data, body, index + 1);
331
0
    if (index >= body->elems)
332
0
        body->elems = index + 1;
333
0
    MVM_ASSIGN_REF(tc, &(root->header), body->child_objs[index], wrapper);
334
0
    ((void **)body->storage)[index] = cptr;
335
0
}
336
0
static void bind_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister value, MVMuint16 kind) {
337
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
338
0
    MVMCArrayBody     *body      = (MVMCArrayBody *)data;
339
0
    void *ptr;
340
0
341
0
    if (body->managed && index >= body->allocated)
342
0
        expand(tc, repr_data, body, index + 1);
343
0
    if (index >= body->elems)
344
0
        body->elems = index + 1;
345
0
346
0
    ptr = ((char *)body->storage) + index * repr_data->elem_size;
347
0
348
0
    switch (repr_data->elem_kind) {
349
0
        case MVM_CARRAY_ELEM_KIND_NUMERIC:
350
0
            if (kind == MVM_reg_int64)
351
0
                REPR(repr_data->elem_type)->box_funcs.set_int(tc,
352
0
                    STABLE(repr_data->elem_type), root, ptr, value.i64);
353
0
            else if (kind == MVM_reg_num64)
354
0
                REPR(repr_data->elem_type)->box_funcs.set_num(tc,
355
0
                    STABLE(repr_data->elem_type), root, ptr, value.n64);
356
0
            else
357
0
                MVM_exception_throw_adhoc(tc, "Wrong kind of access to numeric CArray");
358
0
            break;
359
0
        case MVM_CARRAY_ELEM_KIND_STRING: {
360
0
            char *string = IS_CONCRETE(value.o)
361
0
                         ? MVM_string_utf8_encode_C_string(tc, MVM_repr_get_str(tc, value.o))
362
0
                         : NULL;
363
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o, string);
364
0
            break;
365
0
        }
366
0
        case MVM_CARRAY_ELEM_KIND_CPOINTER:
367
0
            if (REPR(value.o)->ID != MVM_REPR_ID_MVMCPointer)
368
0
                MVM_exception_throw_adhoc(tc, "CArray of CPointer passed non-CPointer object");
369
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o,
370
0
                IS_CONCRETE(value.o) ? ((MVMCPointer *)value.o)->body.ptr : NULL);
371
0
            break;
372
0
        case MVM_CARRAY_ELEM_KIND_CARRAY:
373
0
            if (REPR(value.o)->ID != MVM_REPR_ID_MVMCArray)
374
0
                MVM_exception_throw_adhoc(tc, "CArray of CArray passed non-CArray object");
375
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o,
376
0
                IS_CONCRETE(value.o) ? ((MVMCArray *)value.o)->body.storage : NULL);
377
0
            break;
378
0
        case MVM_CARRAY_ELEM_KIND_CSTRUCT:
379
0
            if (REPR(value.o)->ID != MVM_REPR_ID_MVMCStruct)
380
0
                MVM_exception_throw_adhoc(tc, "CArray of CStruct passed non-CStruct object");
381
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o,
382
0
                IS_CONCRETE(value.o) ? ((MVMCStruct *)value.o)->body.cstruct : NULL);
383
0
            break;
384
0
        case MVM_CARRAY_ELEM_KIND_CPPSTRUCT:
385
0
            if (REPR(value.o)->ID != MVM_REPR_ID_MVMCPPStruct)
386
0
                MVM_exception_throw_adhoc(tc, "CArray of CPPStruct passed non-CStruct object");
387
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o,
388
0
                IS_CONCRETE(value.o) ? ((MVMCPPStruct *)value.o)->body.cppstruct : NULL);
389
0
            break;
390
0
        case MVM_CARRAY_ELEM_KIND_CUNION:
391
0
            if (REPR(value.o)->ID != MVM_REPR_ID_MVMCUnion)
392
0
                MVM_exception_throw_adhoc(tc, "CArray of CUnion passed non-CStruct object");
393
0
            bind_wrapper_and_ptr(tc, root, body, index, value.o,
394
0
                IS_CONCRETE(value.o) ? ((MVMCUnion *)value.o)->body.cunion : NULL);
395
0
            break;
396
0
        default:
397
0
            MVM_exception_throw_adhoc(tc, "Unknown element type in CArray");
398
0
    }
399
0
}
400
401
0
static void push(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister value, MVMuint16 kind) {
402
0
    die_pos_nyi(tc);
403
0
}
404
405
0
static void pop(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind) {
406
0
    die_pos_nyi(tc);
407
0
}
408
409
0
static void unshift(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister value, MVMuint16 kind) {
410
0
    die_pos_nyi(tc);
411
0
}
412
413
0
static void shift(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind) {
414
0
    die_pos_nyi(tc);
415
0
}
416
417
0
static void aslice(MVMThreadContext *tc, MVMSTable *st, MVMObject *src, void *data, MVMObject *dest, MVMint64 start, MVMint64 end) {
418
0
    die_pos_nyi(tc);
419
0
}
420
421
0
static MVMuint64 elems(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
422
0
    MVMCArrayBody *body = (MVMCArrayBody *)data;
423
0
424
0
    if (body->managed)
425
0
        return body->elems;
426
0
427
0
    MVM_exception_throw_adhoc(tc,
428
0
        "Don't know how many elements a C array returned from a library");
429
0
}
430
431
0
static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
432
0
    st->size = sizeof(MVMCArray);
433
0
}
434
435
/* Serializes the REPR data. */
436
0
static void serialize_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMSerializationWriter *writer) {
437
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *)st->REPR_data;
438
0
    MVM_serialization_write_int(tc, writer, repr_data->elem_size);
439
0
    MVM_serialization_write_ref(tc, writer, repr_data->elem_type);
440
0
    MVM_serialization_write_int(tc, writer, repr_data->elem_kind);
441
0
}
442
443
/* Deserializes the REPR data. */
444
0
static void deserialize_repr_data(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
445
0
    MVMCArrayREPRData *repr_data = (MVMCArrayREPRData *) MVM_malloc(sizeof(MVMCArrayREPRData));
446
0
447
0
    if (reader->root.version >= 19) {
448
0
        repr_data->elem_size = MVM_serialization_read_int(tc, reader);
449
0
    } else {
450
0
        repr_data->elem_size = MVM_serialization_read_int64(tc, reader);
451
0
    }
452
0
453
0
    repr_data->elem_type = MVM_serialization_read_ref(tc, reader);
454
0
455
0
    if (reader->root.version >= 19) {
456
0
        repr_data->elem_kind = MVM_serialization_read_int(tc, reader);
457
0
    } else {
458
0
        repr_data->elem_kind = MVM_serialization_read_int64(tc, reader);
459
0
    }
460
0
461
0
    st->REPR_data = repr_data;
462
0
}
463
464
/* Initializes the CArray representation. */
465
144
const MVMREPROps * MVMCArray_initialize(MVMThreadContext *tc) {
466
144
    return &CArray_this_repr;
467
144
}
468
469
static const MVMREPROps CArray_this_repr = {
470
    type_object_for,
471
    MVM_gc_allocate_object,
472
    initialize,
473
    copy_to,
474
    MVM_REPR_DEFAULT_ATTR_FUNCS,
475
    MVM_REPR_DEFAULT_BOX_FUNCS,
476
    {
477
        at_pos,
478
        bind_pos,
479
        MVM_REPR_DEFAULT_SET_ELEMS,
480
        push,
481
        pop,
482
        unshift,
483
        shift,
484
        aslice,
485
        MVM_REPR_DEFAULT_SPLICE,
486
        MVM_REPR_DEFAULT_AT_POS_MULTIDIM,
487
        MVM_REPR_DEFAULT_BIND_POS_MULTIDIM,
488
        MVM_REPR_DEFAULT_DIMENSIONS,
489
        MVM_REPR_DEFAULT_SET_DIMENSIONS,
490
        MVM_REPR_DEFAULT_GET_ELEM_STORAGE_SPEC,
491
        MVM_REPR_DEFAULT_POS_AS_ATOMIC,
492
        MVM_REPR_DEFAULT_POS_AS_ATOMIC_MULTIDIM
493
    },    /* pos_funcs */
494
    MVM_REPR_DEFAULT_ASS_FUNCS,
495
    elems,
496
    get_storage_spec,
497
    NULL, /* change_type */
498
    NULL, /* serialize */
499
    NULL, /* deserialize */
500
    serialize_repr_data,
501
    deserialize_repr_data,
502
    deserialize_stable_size,
503
    gc_mark,
504
    gc_free,
505
    gc_cleanup,
506
    gc_mark_repr_data,
507
    gc_free_repr_data,
508
    compose,
509
    NULL, /* spesh */
510
    "CArray", /* name */
511
    MVM_REPR_ID_MVMCArray,
512
    NULL, /* unmanaged_size */
513
    NULL, /* describe_refs */
514
};