Coverage Report

Created: 2018-06-21 18:56

/home/travis/build/MoarVM/MoarVM/src/6model/bootstrap.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* This file implements the various steps involved in getting 6model
4
 * bootstrapped from the ground up - that is, getting to having a
5
 * KnowHOW meta-object type so that userland can start building up
6
 * more interesting meta-objects. Mostly it just has to make objects
7
 * with some "holes", and later go back and fill them out. This is
8
 * due to the circular nature of things.
9
 */
10
11
/* Creates a stub VMString. Note we didn't initialize the
12
 * representation yet, so have to do this somewhat pokily. */
13
144
static void create_stub_VMString(MVMThreadContext *tc) {
14
144
    /* Need to create the REPR function table "in advance". */
15
144
    const MVMREPROps *repr = MVMString_initialize(tc);
16
144
17
144
    /* Now we can create a type object; note we have no HOW yet,
18
144
     * though. */
19
144
    tc->instance->VMString = repr->type_object_for(tc, NULL);
20
144
}
21
22
/* KnowHOW.new_type method. Creates a new type with this HOW as its meta-object. */
23
1.17k
static void new_type(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
24
1.17k
    MVMObject *self, *HOW, *type_object, *BOOTHash, *stash;
25
1.17k
    MVMArgInfo repr_arg, name_arg;
26
1.17k
    MVMString *repr_name, *name;
27
1.17k
    const MVMREPROps *repr_to_use;
28
1.17k
    MVMInstance       *instance = tc->instance;
29
1.17k
30
1.17k
    /* Get arguments. */
31
1.17k
    MVMArgProcContext arg_ctx;
32
1.17k
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
33
1.17k
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
34
1.17k
    self = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
35
1.17k
    repr_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.repr, MVM_ARG_OPTIONAL);
36
1.17k
    name_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.name, MVM_ARG_OPTIONAL);
37
1.17k
    MVM_args_proc_cleanup(tc, &arg_ctx);
38
1.17k
    if (REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
39
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object with REPR KnowHOWREPR");
40
1.17k
41
1.17k
    /* See if we have a representation name; if not default to P6opaque. */
42
1.01k
    repr_name = repr_arg.exists ? repr_arg.arg.s : instance->str_consts.P6opaque;
43
1.17k
    repr_to_use = MVM_repr_get_by_name(tc, repr_name);
44
1.17k
45
1.17k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&name_arg);
46
1.17k
47
1.17k
    /* We first create a new HOW instance. */
48
1.17k
    HOW = REPR(self)->allocate(tc, STABLE(self));
49
1.17k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&HOW);
50
1.17k
51
1.17k
    /* Create a new type object of the desired REPR. (Note that we can't
52
1.17k
     * default to KnowHOWREPR here, since it doesn't know how to actually
53
1.17k
     * store attributes, it's just for bootstrapping knowhow's. */
54
1.17k
    type_object = repr_to_use->type_object_for(tc, HOW);
55
1.17k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_object);
56
1.17k
57
1.17k
    /* This may move name_arg.arg.s so do it first: */
58
1.17k
    REPR(HOW)->initialize(tc, STABLE(HOW), HOW, OBJECT_BODY(HOW));
59
1.17k
    /* See if we were given a name; put it into the meta-object if so. */
60
1.02k
    name = name_arg.exists ? name_arg.arg.s : instance->str_consts.anon;
61
1.17k
    MVM_ASSIGN_REF(tc, &(HOW->header), ((MVMKnowHOWREPR *)HOW)->body.name, name);
62
1.17k
    type_object->st->debug_name = MVM_string_utf8_encode_C_string(tc, name);
63
1.17k
64
1.17k
    /* Set .WHO to an empty hash. */
65
1.17k
    BOOTHash = tc->instance->boot_types.BOOTHash;
66
1.17k
    stash = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
67
1.17k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&stash);
68
1.17k
    MVM_ASSIGN_REF(tc, &(STABLE(type_object)->header), STABLE(type_object)->WHO, stash);
69
1.17k
70
1.17k
    /* Return the type object. */
71
1.17k
    MVM_args_set_result_obj(tc, type_object, MVM_RETURN_CURRENT_FRAME);
72
1.17k
73
1.17k
    MVM_gc_root_temp_pop_n(tc, 4);
74
1.17k
}
75
76
/* Adds a method. */
77
13
static void add_method(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
78
13
    MVMObject *self, *method, *method_table;
79
13
    MVMString *name;
80
13
81
13
    /* Get arguments. */
82
13
    MVMArgProcContext arg_ctx;
83
13
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
84
13
    MVM_args_checkarity(tc, &arg_ctx, 4, 4);
85
13
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
86
13
    name     = MVM_args_get_required_pos_str(tc, &arg_ctx, 2);
87
13
    method   = MVM_args_get_required_pos_obj(tc, &arg_ctx, 3);
88
13
    MVM_args_proc_cleanup(tc, &arg_ctx);
89
13
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
90
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
91
13
92
13
    /* Add to method table. */
93
13
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
94
13
    MVM_repr_bind_key_o(tc, method_table, name, method);
95
13
96
13
    /* Return added method as result. */
97
13
    MVM_args_set_result_obj(tc, method, MVM_RETURN_CURRENT_FRAME);
98
13
}
99
100
/* Adds an method. */
101
5
static void add_attribute(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
102
5
    MVMObject *self, *attr, *attributes;
103
5
104
5
    /* Get arguments. */
105
5
    MVMArgProcContext arg_ctx;
106
5
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
107
5
    MVM_args_checkarity(tc, &arg_ctx, 3, 3);
108
5
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
109
5
    attr     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 2);
110
5
    MVM_args_proc_cleanup(tc, &arg_ctx);
111
5
112
5
    /* Ensure we have the required representations. */
113
5
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
114
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
115
5
    if (REPR(attr)->ID != MVM_REPR_ID_KnowHOWAttributeREPR)
116
0
        MVM_exception_throw_adhoc(tc, "KnowHOW attributes must use KnowHOWAttributeREPR");
117
5
118
5
    /* Add to method table. */
119
5
    attributes = ((MVMKnowHOWREPR *)self)->body.attributes;
120
5
    MVM_repr_push_o(tc, attributes, attr);
121
5
122
5
    /* Return added attribute as result. */
123
5
    MVM_args_set_result_obj(tc, attr, MVM_RETURN_CURRENT_FRAME);
124
5
}
125
126
/* Composes the meta-object. */
127
1.02k
static void compose(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
128
1.02k
    MVMObject *self, *type_obj, *method_table, *attributes, *BOOTArray, *BOOTHash,
129
1.02k
              *repr_info_hash, *repr_info, *type_info, *attr_info_list, *parent_info;
130
1.02k
    MVMuint64   num_attrs, i;
131
1.02k
    MVMInstance *instance = tc->instance;
132
1.02k
133
1.02k
    /* Get arguments. */
134
1.02k
    MVMArgProcContext arg_ctx;
135
1.02k
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
136
1.02k
    MVM_args_checkarity(tc, &arg_ctx, 2, 2);
137
1.02k
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
138
1.02k
    type_obj = MVM_args_get_required_pos_obj(tc, &arg_ctx, 1);
139
1.02k
    MVM_args_proc_cleanup(tc, &arg_ctx);
140
1.02k
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
141
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
142
1.02k
143
1.02k
    /* Fill out STable. */
144
1.02k
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
145
1.02k
    MVM_ASSIGN_REF(tc, &(STABLE(type_obj)->header), STABLE(type_obj)->method_cache, method_table);
146
1.02k
    STABLE(type_obj)->mode_flags              = MVM_METHOD_CACHE_AUTHORITATIVE;
147
1.02k
    STABLE(type_obj)->type_check_cache_length = 1;
148
1.02k
    STABLE(type_obj)->type_check_cache        = MVM_malloc(sizeof(MVMObject *));
149
1.02k
    MVM_ASSIGN_REF(tc, &(STABLE(type_obj)->header), STABLE(type_obj)->type_check_cache[0], type_obj);
150
1.02k
    attributes = ((MVMKnowHOWREPR *)self)->body.attributes;
151
1.02k
152
1.02k
    /* Next steps will allocate, so make sure we keep hold of the type
153
1.02k
     * object and ourself. */
154
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attributes);
155
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_obj);
156
1.02k
157
1.02k
    /* Use any attribute information to produce attribute protocol
158
1.02k
     * data. The protocol consists of an array... */
159
1.02k
    BOOTArray = instance->boot_types.BOOTArray;
160
1.02k
    BOOTHash = instance->boot_types.BOOTHash;
161
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTArray);
162
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTHash);
163
1.02k
    repr_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
164
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&repr_info);
165
1.02k
166
1.02k
    /* ...which contains an array per MRO entry (just us)... */
167
1.02k
    type_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
168
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_info);
169
1.02k
    MVM_repr_push_o(tc, repr_info, type_info);
170
1.02k
171
1.02k
    /* ...which in turn contains this type... */
172
1.02k
    MVM_repr_push_o(tc, type_info, type_obj);
173
1.02k
174
1.02k
    /* ...then an array of hashes per attribute... */
175
1.02k
    attr_info_list = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
176
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_info_list);
177
1.02k
    MVM_repr_push_o(tc, type_info, attr_info_list);
178
1.02k
    num_attrs = REPR(attributes)->elems(tc, STABLE(attributes),
179
1.02k
        attributes, OBJECT_BODY(attributes));
180
1.03k
    for (i = 0; i < num_attrs; i++) {
181
5
        MVMObject *attr_info = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
182
5
        MVMKnowHOWAttributeREPR *attribute = (MVMKnowHOWAttributeREPR *)
183
5
            MVM_repr_at_pos_o(tc, attributes, i);
184
5
        MVMROOT2(tc, attr_info, attribute, {
185
5
            if (REPR((MVMObject *)attribute)->ID != MVM_REPR_ID_KnowHOWAttributeREPR)
186
5
                MVM_exception_throw_adhoc(tc, "KnowHOW attributes must use KnowHOWAttributeREPR");
187
5
188
5
            MVM_repr_init(tc, attr_info);
189
5
            MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.name, (MVMObject *)attribute->body.name);
190
5
            MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.type, attribute->body.type);
191
5
            if (attribute->body.box_target) {
192
5
                /* Merely having the key serves as a "yes". */
193
5
                MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.box_target, attr_info);
194
5
            }
195
5
196
5
            MVM_repr_push_o(tc, attr_info_list, attr_info);
197
5
        });
198
5
    }
199
1.02k
200
1.02k
    /* ...followed by a list of parents (none). */
201
1.02k
    parent_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
202
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&parent_info);
203
1.02k
    MVM_repr_init(tc, parent_info);
204
1.02k
    MVM_repr_push_o(tc, type_info, parent_info);
205
1.02k
206
1.02k
    /* Finally, this all goes in a hash under the key 'attribute'. */
207
1.02k
    repr_info_hash = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
208
1.02k
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&repr_info_hash);
209
1.02k
    MVM_repr_init(tc, repr_info_hash);
210
1.02k
    MVM_repr_bind_key_o(tc, repr_info_hash, instance->str_consts.attribute, repr_info);
211
1.02k
212
1.02k
    /* Compose the representation using it. */
213
1.02k
    MVM_repr_compose(tc, type_obj, repr_info_hash);
214
1.02k
215
1.02k
    /* Clear temporary roots. */
216
1.02k
    MVM_gc_root_temp_pop_n(tc, 9);
217
1.02k
218
1.02k
    /* Return type object. */
219
1.02k
    MVM_args_set_result_obj(tc, type_obj, MVM_RETURN_CURRENT_FRAME);
220
1.02k
}
221
222
#define introspect_member(member, set_result, result) \
223
2.56k
static void member(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) { \
224
2.56k
    MVMObject *self, *type_obj, *member; \
225
2.56k
    MVMArgProcContext arg_ctx; \
226
2.56k
    MVM_args_proc_init(tc, &arg_ctx, callsite, args); \
227
2.56k
    MVM_args_checkarity(tc, &arg_ctx, 2, 2); \
228
2.56k
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0); \
229
2.56k
    type_obj = MVM_args_get_required_pos_obj(tc, &arg_ctx, 1); \
230
2.56k
    MVM_args_proc_cleanup(tc, &arg_ctx); \
231
2.56k
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR) \
232
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR"); \
233
2.56k
    member = (MVMObject *)((MVMKnowHOWREPR *)self)->body.member; \
234
2.56k
    set_result(tc, result, MVM_RETURN_CURRENT_FRAME); \
235
2.56k
}
bootstrap.c:attributes
Line
Count
Source
223
5
static void member(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) { \
224
5
    MVMObject *self, *type_obj, *member; \
225
5
    MVMArgProcContext arg_ctx; \
226
5
    MVM_args_proc_init(tc, &arg_ctx, callsite, args); \
227
5
    MVM_args_checkarity(tc, &arg_ctx, 2, 2); \
228
5
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0); \
229
5
    type_obj = MVM_args_get_required_pos_obj(tc, &arg_ctx, 1); \
230
5
    MVM_args_proc_cleanup(tc, &arg_ctx); \
231
5
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR) \
232
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR"); \
233
5
    member = (MVMObject *)((MVMKnowHOWREPR *)self)->body.member; \
234
5
    set_result(tc, result, MVM_RETURN_CURRENT_FRAME); \
235
5
}
bootstrap.c:methods
Line
Count
Source
223
3
static void member(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) { \
224
3
    MVMObject *self, *type_obj, *member; \
225
3
    MVMArgProcContext arg_ctx; \
226
3
    MVM_args_proc_init(tc, &arg_ctx, callsite, args); \
227
3
    MVM_args_checkarity(tc, &arg_ctx, 2, 2); \
228
3
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0); \
229
3
    type_obj = MVM_args_get_required_pos_obj(tc, &arg_ctx, 1); \
230
3
    MVM_args_proc_cleanup(tc, &arg_ctx); \
231
3
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR) \
232
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR"); \
233
3
    member = (MVMObject *)((MVMKnowHOWREPR *)self)->body.member; \
234
3
    set_result(tc, result, MVM_RETURN_CURRENT_FRAME); \
235
3
}
bootstrap.c:name
Line
Count
Source
223
2.55k
static void member(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) { \
224
2.55k
    MVMObject *self, *type_obj, *member; \
225
2.55k
    MVMArgProcContext arg_ctx; \
226
2.55k
    MVM_args_proc_init(tc, &arg_ctx, callsite, args); \
227
2.55k
    MVM_args_checkarity(tc, &arg_ctx, 2, 2); \
228
2.55k
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0); \
229
2.55k
    type_obj = MVM_args_get_required_pos_obj(tc, &arg_ctx, 1); \
230
2.55k
    MVM_args_proc_cleanup(tc, &arg_ctx); \
231
2.55k
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR) \
232
0
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR"); \
233
2.55k
    member = (MVMObject *)((MVMKnowHOWREPR *)self)->body.member; \
234
2.55k
    set_result(tc, result, MVM_RETURN_CURRENT_FRAME); \
235
2.55k
}
236
237
/* Introspects the attributes. For now just hand back real list. */
238
introspect_member(attributes, MVM_args_set_result_obj, attributes)
239
240
/* Introspects the methods. */
241
introspect_member(methods, MVM_args_set_result_obj, methods)
242
243
/* Introspects the name. */
244
introspect_member(name, MVM_args_set_result_str, (MVMString *)name)
245
246
/* Adds a method into the KnowHOW.HOW method table. */
247
static void add_knowhow_how_method(MVMThreadContext *tc, MVMKnowHOWREPR *knowhow_how,
248
1.72k
        char *name, void (*func) (MVMThreadContext *, MVMCallsite *, MVMRegister *)) {
249
1.72k
    MVMObject *BOOTCCode, *code_obj, *method_table;
250
1.72k
    MVMString *name_str;
251
1.72k
252
1.72k
    /* Create string for name. */
253
1.72k
    name_str = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, name);
254
1.72k
255
1.72k
    /* Allocate a BOOTCCode and put pointer in. */
256
1.72k
    BOOTCCode = tc->instance->boot_types.BOOTCCode;
257
1.72k
    code_obj = REPR(BOOTCCode)->allocate(tc, STABLE(BOOTCCode));
258
1.72k
    ((MVMCFunction *)code_obj)->body.func = func;
259
1.72k
260
1.72k
    /* Add into the table. */
261
1.72k
    method_table = knowhow_how->body.methods;
262
1.72k
    MVM_repr_bind_key_o(tc, method_table, name_str, code_obj);
263
1.72k
}
264
265
/* Bootstraps the KnowHOW type. */
266
144
static void bootstrap_KnowHOW(MVMThreadContext *tc) {
267
144
    MVMObject *VMString  = tc->instance->VMString;
268
144
269
144
    /* Create our KnowHOW type object. Note we don't have a HOW just yet, so
270
144
     * pass in NULL. */
271
144
    const MVMREPROps *REPR    = MVM_repr_get_by_id(tc, MVM_REPR_ID_KnowHOWREPR);
272
144
    MVMObject  *knowhow = REPR->type_object_for(tc, NULL);
273
144
274
144
    /* We create a KnowHOW instance that can describe itself. This means
275
144
     * (once we tie the knot) that .HOW.HOW.HOW.HOW etc will always return
276
144
     * that, which closes the model up. Note that the STable for it must
277
144
     * be allocated first, since that holds the allocation size. */
278
144
    MVMKnowHOWREPR *knowhow_how;
279
144
    MVMSTable *st = MVM_gc_allocate_stable(tc, REPR, NULL);
280
144
    st->WHAT      = (MVMObject *)knowhow;
281
144
    st->size      = sizeof(MVMKnowHOWREPR);
282
144
    knowhow_how   = (MVMKnowHOWREPR *)REPR->allocate(tc, st);
283
144
    st->HOW       = (MVMObject *)knowhow_how;
284
144
    knowhow_how->common.st = st;
285
144
286
144
    /* Add various methods to the KnowHOW's HOW. */
287
144
    REPR->initialize(tc, NULL, (MVMObject *)knowhow_how, &knowhow_how->body);
288
144
    add_knowhow_how_method(tc, knowhow_how, "new_type", new_type);
289
144
    add_knowhow_how_method(tc, knowhow_how, "add_method", add_method);
290
144
    add_knowhow_how_method(tc, knowhow_how, "add_attribute", add_attribute);
291
144
    add_knowhow_how_method(tc, knowhow_how, "compose", compose);
292
144
    add_knowhow_how_method(tc, knowhow_how, "attributes", attributes);
293
144
    add_knowhow_how_method(tc, knowhow_how, "methods", methods);
294
144
    add_knowhow_how_method(tc, knowhow_how, "name", name);
295
144
296
144
    /* Set name KnowHOW for the KnowHOW's HOW. */
297
144
    knowhow_how->body.name = MVM_string_ascii_decode_nt(tc, VMString, "KnowHOW");
298
144
299
144
    /* Set this built up HOW as the KnowHOW's HOW. */
300
144
    STABLE(knowhow)->HOW = (MVMObject *)knowhow_how;
301
144
302
144
    /* Give it an authoritative method cache; this in turn will make the
303
144
     * method dispatch bottom out. */
304
144
    STABLE(knowhow)->method_cache = knowhow_how->body.methods;
305
144
    STABLE(knowhow)->mode_flags   = MVM_METHOD_CACHE_AUTHORITATIVE;
306
144
    STABLE(knowhow_how)->method_cache = knowhow_how->body.methods;
307
144
    STABLE(knowhow_how)->mode_flags   = MVM_METHOD_CACHE_AUTHORITATIVE;
308
144
309
144
    /* Stash the created KnowHOW. */
310
144
    tc->instance->KnowHOW = (MVMObject *)knowhow;
311
144
    MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&tc->instance->KnowHOW, "KnowHOW");
312
144
}
313
314
/* Takes a stub object that existed before we had bootstrapped things and
315
 * gives it a meta-object. */
316
3.88k
static void add_meta_object(MVMThreadContext *tc, MVMObject *type_obj, char *name) {
317
3.88k
    MVMObject *meta_obj;
318
3.88k
    MVMString *name_str;
319
3.88k
320
3.88k
    /* Create meta-object. */
321
3.88k
    meta_obj = MVM_repr_alloc_init(tc, STABLE(tc->instance->KnowHOW)->HOW);
322
3.88k
    MVMROOT(tc, meta_obj, {
323
3.88k
        /* Put it in place. */
324
3.88k
        MVM_ASSIGN_REF(tc, &(STABLE(type_obj)->header), STABLE(type_obj)->HOW, meta_obj);
325
3.88k
326
3.88k
        /* Set name. */
327
3.88k
        name_str = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, name);
328
3.88k
        MVM_ASSIGN_REF(tc, &(meta_obj->header), ((MVMKnowHOWREPR *)meta_obj)->body.name, name_str);
329
3.88k
        type_obj->st->debug_name = strdup(name);
330
3.88k
    });
331
3.88k
}
332
333
/* Creates a new attribute meta-object. */
334
6
static void attr_new(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
335
6
    MVMObject   *self, *obj;
336
6
    MVMArgInfo   type_arg, name_arg, bt_arg;
337
6
    const MVMREPROps  *repr;
338
6
    MVMInstance       *instance = tc->instance;
339
6
340
6
    /* Process arguments. */
341
6
    MVMArgProcContext arg_ctx;
342
6
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
343
6
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
344
6
    self     = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
345
6
    name_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.name, MVM_ARG_REQUIRED);
346
6
    type_arg = MVM_args_get_named_obj(tc, &arg_ctx, instance->str_consts.type, MVM_ARG_OPTIONAL);
347
6
    bt_arg   = MVM_args_get_named_int(tc, &arg_ctx, instance->str_consts.box_target, MVM_ARG_OPTIONAL);
348
6
    MVM_args_proc_cleanup(tc, &arg_ctx);
349
6
350
6
    /* Anchor all the things. */
351
6
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&name_arg);
352
6
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_arg);
353
6
354
6
    /* Allocate attribute object. */
355
6
    repr = MVM_repr_get_by_id(tc, MVM_REPR_ID_KnowHOWAttributeREPR);
356
6
    obj = repr->allocate(tc, STABLE(self));
357
6
358
6
    /* Populate it. */
359
6
    MVM_ASSIGN_REF(tc, &(obj->header), ((MVMKnowHOWAttributeREPR *)obj)->body.name, name_arg.arg.s);
360
6
    MVM_ASSIGN_REF(tc, &(obj->header), ((MVMKnowHOWAttributeREPR *)obj)->body.type, type_arg.exists ? type_arg.arg.o : tc->instance->KnowHOW);
361
6
    ((MVMKnowHOWAttributeREPR *)obj)->body.box_target = bt_arg.exists ? bt_arg.arg.i64 : 0;
362
6
363
6
    /* Return produced object. */
364
6
    MVM_gc_root_temp_pop_n(tc, 2);
365
6
    MVM_args_set_result_obj(tc, obj, MVM_RETURN_CURRENT_FRAME);
366
6
}
367
368
/* Composes the attribute; actually, nothing to do really. */
369
0
static void attr_compose(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
370
0
    MVMObject *self;
371
0
    MVMArgProcContext arg_ctx;
372
0
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
373
0
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
374
0
    self = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
375
0
    MVM_args_proc_cleanup(tc, &arg_ctx);
376
0
    MVM_args_set_result_obj(tc, self, MVM_RETURN_CURRENT_FRAME);
377
0
}
378
379
/* Introspects the attribute's name. */
380
6
static void attr_name(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
381
6
    MVMObject *self;
382
6
    MVMString *name;
383
6
    MVMArgProcContext arg_ctx;
384
6
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
385
6
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
386
6
    self = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
387
6
    MVM_args_proc_cleanup(tc, &arg_ctx);
388
6
    name = ((MVMKnowHOWAttributeREPR *)self)->body.name;
389
6
    MVM_args_set_result_str(tc, name, MVM_RETURN_CURRENT_FRAME);
390
6
}
391
392
/* Introspects the attribute's type. */
393
4
static void attr_type(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
394
4
    MVMObject *self, *type;
395
4
    MVMArgProcContext arg_ctx;
396
4
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
397
4
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
398
4
    self = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
399
4
    MVM_args_proc_cleanup(tc, &arg_ctx);
400
4
    type = ((MVMKnowHOWAttributeREPR *)self)->body.type;
401
4
    MVM_args_set_result_obj(tc, type, MVM_RETURN_CURRENT_FRAME);
402
4
}
403
404
/* Introspects the attribute's box target flag. */
405
0
static void attr_box_target(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
406
0
    MVMObject *self;
407
0
    MVMint64   box_target;
408
0
    MVMArgProcContext arg_ctx;
409
0
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
410
0
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
411
0
    self = MVM_args_get_required_pos_obj(tc, &arg_ctx, 0);
412
0
    MVM_args_proc_cleanup(tc, &arg_ctx);
413
0
    box_target = ((MVMKnowHOWAttributeREPR *)self)->body.box_target;
414
0
    MVM_args_set_result_int(tc, box_target, MVM_RETURN_CURRENT_FRAME);
415
0
}
416
417
/* Creates and installs the KnowHOWAttribute type. */
418
144
static void create_KnowHOWAttribute(MVMThreadContext *tc) {
419
144
    MVMObject      *meta_obj, *type_obj;
420
144
    MVMString      *name_str;
421
144
    const MVMREPROps     *repr;
422
144
423
144
    /* Create meta-object. */
424
144
    meta_obj = MVM_repr_alloc_init(tc, STABLE(tc->instance->KnowHOW)->HOW);
425
144
    MVMROOT(tc, meta_obj, {
426
144
        /* Add methods. */
427
144
        add_knowhow_how_method(tc, (MVMKnowHOWREPR *)meta_obj, "new", attr_new);
428
144
        add_knowhow_how_method(tc, (MVMKnowHOWREPR *)meta_obj, "compose", attr_compose);
429
144
        add_knowhow_how_method(tc, (MVMKnowHOWREPR *)meta_obj, "name", attr_name);
430
144
        add_knowhow_how_method(tc, (MVMKnowHOWREPR *)meta_obj, "type", attr_type);
431
144
        add_knowhow_how_method(tc, (MVMKnowHOWREPR *)meta_obj, "box_target", attr_box_target);
432
144
433
144
        /* Set name. */
434
144
        name_str = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "KnowHOWAttribute");
435
144
        MVM_ASSIGN_REF(tc, &(meta_obj->header), ((MVMKnowHOWREPR *)meta_obj)->body.name, name_str);
436
144
437
144
        /* Create a new type object with the correct REPR. */
438
144
        repr = MVM_repr_get_by_id(tc, MVM_REPR_ID_KnowHOWAttributeREPR);
439
144
        type_obj = repr->type_object_for(tc, meta_obj);
440
144
441
144
        /* Set up method dispatch cache. */
442
144
        STABLE(type_obj)->method_cache = ((MVMKnowHOWREPR *)meta_obj)->body.methods;
443
144
        STABLE(type_obj)->mode_flags   = MVM_METHOD_CACHE_AUTHORITATIVE;
444
144
445
144
        /* Stash the created type object. */
446
144
        tc->instance->KnowHOWAttribute = (MVMObject *)type_obj;
447
144
        MVM_gc_root_add_permanent_desc(tc,
448
144
            (MVMCollectable **)&tc->instance->KnowHOWAttribute,
449
144
            "KnowHOWAttribute");
450
144
    });
451
144
}
452
453
/* Bootstraps a typed array. */
454
432
static MVMObject * boot_typed_array(MVMThreadContext *tc, char *name, MVMObject *type) {
455
432
    MVMBoolificationSpec *bs;
456
432
    MVMObject  *repr_info;
457
432
    MVMInstance  *instance  = tc->instance;
458
432
    const MVMREPROps *repr  = MVM_repr_get_by_id(tc, MVM_REPR_ID_VMArray);
459
432
    MVMObject  *array = repr->type_object_for(tc, NULL);
460
432
    MVMROOT(tc, array, {
461
432
        /* Give it a meta-object. */
462
432
        add_meta_object(tc, array, name);
463
432
464
432
        /* Now need to compose it with the specified type. */
465
432
        repr_info = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTHash);
466
432
        MVMROOT(tc, repr_info, {
467
432
            MVMObject *arr_info = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTHash);
468
432
            MVM_repr_bind_key_o(tc, arr_info, instance->str_consts.type, type);
469
432
            MVM_repr_bind_key_o(tc, repr_info, instance->str_consts.array, arr_info);
470
432
            MVM_repr_compose(tc, array, repr_info);
471
432
        });
472
432
473
432
        /* Also give it a boolification spec. */
474
432
        bs = MVM_malloc(sizeof(MVMBoolificationSpec));
475
432
        bs->mode = MVM_BOOL_MODE_HAS_ELEMS;
476
432
        bs->method = NULL;
477
432
        array->st->boolification_spec = bs;
478
432
    });
479
432
    return array;
480
432
}
481
482
/* Sets up the core serialization context. It is marked as the SC of various
483
 * rooted objects, which means in turn it will never be collected. */
484
144
static void setup_core_sc(MVMThreadContext *tc) {
485
144
    MVMString *handle = MVM_string_ascii_decode_nt(tc,
486
144
        tc->instance->VMString, "__6MODEL_CORE__");
487
144
    MVMSerializationContext * const sc = (MVMSerializationContext *)MVM_sc_create(tc, handle);
488
144
    MVMint32 obj_index = 0;
489
144
    MVMint32 st_index  = 0;
490
144
491
1.44k
#define add_to_sc_with_st(tc, sc, variable) do { \
492
1.44k
    MVM_sc_set_object(tc, sc, obj_index++, variable); \
493
1.44k
    MVM_sc_set_obj_sc(tc, variable, sc); \
494
1.44k
    MVM_sc_set_stable(tc, sc, st_index++, STABLE(variable)); \
495
1.44k
    MVM_sc_set_stable_sc(tc, STABLE(variable), sc); \
496
1.44k
} while (0)
497
1.00k
#define add_to_sc_with_st_and_mo(tc, sc, variable) do { \
498
1.00k
    add_to_sc_with_st(tc, sc, variable); \
499
1.00k
    MVM_sc_set_object(tc, sc, obj_index++, STABLE(variable)->HOW); \
500
1.00k
    MVM_sc_set_obj_sc(tc, STABLE(variable)->HOW, sc); \
501
1.00k
} while (0)
502
144
503
144
    /* KnowHOW */
504
144
    add_to_sc_with_st(tc, sc, tc->instance->KnowHOW);
505
144
506
144
    /* KnowHOW.HOW */
507
144
    add_to_sc_with_st(tc, sc, STABLE(tc->instance->KnowHOW)->HOW);
508
144
509
144
    /* KnowHOWAttribute */
510
144
    add_to_sc_with_st(tc, sc, tc->instance->KnowHOWAttribute);
511
144
512
144
    /* BOOT* */
513
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTArray);
514
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTHash);
515
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTIter);
516
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTInt);
517
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTNum);
518
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTStr);
519
144
    add_to_sc_with_st_and_mo(tc, sc, tc->instance->boot_types.BOOTCode);
520
144
}
521
522
/* Sets up some string constants. */
523
144
static void string_consts(MVMThreadContext *tc) {
524
144
    MVMInstance * const instance = tc->instance;
525
144
526
144
/* Set up some strings. */
527
7.77k
#define string_creator(variable, name) do { \
528
144
    instance->str_consts.variable = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, (name)); \
529
7.77k
    MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&(instance->str_consts.variable), "VM string constant"); \
530
7.77k
} while (0)
531
144
532
144
    string_creator(empty, "");
533
144
    string_creator(Str, "Str");
534
144
    string_creator(Num, "Num");
535
144
    string_creator(integer, "integer");
536
144
    string_creator(float_str, "float");
537
144
    string_creator(bits, "bits");
538
144
    string_creator(unsigned_str, "unsigned");
539
144
    string_creator(find_method, "find_method");
540
144
    string_creator(type_check, "type_check");
541
144
    string_creator(accepts_type, "accepts_type");
542
144
    string_creator(name, "name");
543
144
    string_creator(attribute, "attribute");
544
144
    string_creator(of, "of");
545
144
    string_creator(rw, "rw");
546
144
    string_creator(type, "type");
547
144
    string_creator(typeobj, "typeobj");
548
144
    string_creator(free_str, "free_str");
549
144
    string_creator(callback_args, "callback_args");
550
144
    string_creator(encoding, "encoding");
551
144
    string_creator(inlined, "inlined");
552
144
    string_creator(repr, "repr");
553
144
    string_creator(anon, "<anon>");
554
144
    string_creator(P6opaque, "P6opaque");
555
144
    string_creator(box_target, "box_target");
556
144
    string_creator(array, "array");
557
144
    string_creator(positional_delegate, "positional_delegate");
558
144
    string_creator(associative_delegate, "associative_delegate");
559
144
    string_creator(auto_viv_container, "auto_viv_container");
560
144
    string_creator(done, "done");
561
144
    string_creator(error, "error");
562
144
    string_creator(stdout_bytes, "stdout_bytes");
563
144
    string_creator(stderr_bytes, "stderr_bytes");
564
144
    string_creator(merge_bytes, "merge_bytes");
565
144
    string_creator(buf_type, "buf_type");
566
144
    string_creator(write, "write");
567
144
    string_creator(stdin_fd, "stdin_fd");
568
144
    string_creator(stdout_fd, "stdout_fd");
569
144
    string_creator(stderr_fd, "stderr_fd");
570
144
    string_creator(nativeref, "nativeref");
571
144
    string_creator(refkind, "refkind");
572
144
    string_creator(positional, "positional");
573
144
    string_creator(lexical, "lexical");
574
144
    string_creator(dimensions, "dimensions");
575
144
    string_creator(ready, "ready");
576
144
    string_creator(multidim, "multidim");
577
144
    string_creator(entry_point, "entry_point");
578
144
    string_creator(kind, "kind");
579
144
    string_creator(instrumented, "instrumented");
580
144
    string_creator(heap, "heap");
581
144
    string_creator(translate_newlines, "translate_newlines");
582
144
    string_creator(platform_newline, MVM_TRANSLATE_NEWLINE_OUTPUT ? "\r\n" : "\n");
583
144
    string_creator(path, "path");
584
144
    string_creator(config, "config");
585
144
    string_creator(replacement, "replacement");
586
144
}
587
588
/* Drives the overall bootstrap process. */
589
144
void MVM_6model_bootstrap(MVMThreadContext *tc) {
590
144
    /* First, we have to get the VMString type to exist; this has to
591
144
     * come even before REPR registry setup because it relies on
592
144
     * being able to create strings. */
593
144
    create_stub_VMString(tc);
594
144
595
144
    /* Set up some string constants commonly used. */
596
144
    string_consts(tc);
597
144
598
144
    /* Now we've enough to actually create the REPR registry. */
599
144
    MVM_repr_initialize_registry(tc);
600
144
601
144
    /* Create stub VMNull, BOOTInt, BOOTNum, BOOTStr, BOOTArray, BOOTHash,
602
144
     * BOOTCCode, BOOTCode, BOOTThread, BOOTIter, BOOTContext, SCRef,
603
144
     * CallCapture, BOOTIO, BOOTException, BOOTQueue, BOOTAsync,
604
144
     * and BOOTReentrantMutex types. */
605
3.60k
#define create_stub_boot_type(tc, reprid, slot, makeboolspec, boolspec) do { \
606
3.60k
    const MVMREPROps *repr = MVM_repr_get_by_id(tc, reprid); \
607
3.60k
    MVMObject *type = tc->instance->slot = repr->type_object_for(tc, NULL); \
608
3.60k
    if (makeboolspec) { \
609
864
        MVMBoolificationSpec *bs; \
610
864
        bs = MVM_malloc(sizeof(MVMBoolificationSpec)); \
611
864
        bs->mode = boolspec; \
612
864
        bs->method = NULL; \
613
864
        type->st->boolification_spec = bs; \
614
864
    } \
615
3.60k
} while (0)
616
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMNull, VMNull, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
617
144
    create_stub_boot_type(tc, MVM_REPR_ID_P6int, boot_types.BOOTInt, 1, MVM_BOOL_MODE_UNBOX_INT);
618
144
    create_stub_boot_type(tc, MVM_REPR_ID_P6num, boot_types.BOOTNum, 1, MVM_BOOL_MODE_UNBOX_NUM);
619
144
    create_stub_boot_type(tc, MVM_REPR_ID_P6str, boot_types.BOOTStr, 1, MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY);
620
144
    create_stub_boot_type(tc, MVM_REPR_ID_VMArray, boot_types.BOOTArray, 1, MVM_BOOL_MODE_HAS_ELEMS);
621
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMHash, boot_types.BOOTHash, 1, MVM_BOOL_MODE_HAS_ELEMS);
622
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMCFunction, boot_types.BOOTCCode, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
623
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMCode, boot_types.BOOTCode, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
624
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMThread, boot_types.BOOTThread, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
625
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMIter, boot_types.BOOTIter, 1, MVM_BOOL_MODE_ITER);
626
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMContext, boot_types.BOOTContext, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
627
144
    create_stub_boot_type(tc, MVM_REPR_ID_SCRef, SCRef, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
628
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMCallCapture, CallCapture, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
629
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMOSHandle, boot_types.BOOTIO, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
630
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMException, boot_types.BOOTException, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
631
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMStaticFrame, boot_types.BOOTStaticFrame, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
632
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMCompUnit, boot_types.BOOTCompUnit, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
633
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMMultiCache, boot_types.BOOTMultiCache, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
634
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMContinuation, boot_types.BOOTContinuation, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
635
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMThread, Thread, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
636
144
    create_stub_boot_type(tc, MVM_REPR_ID_ConcBlockingQueue, boot_types.BOOTQueue, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
637
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMAsyncTask, boot_types.BOOTAsync, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
638
144
    create_stub_boot_type(tc, MVM_REPR_ID_ReentrantMutex, boot_types.BOOTReentrantMutex, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
639
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMSpeshLog, SpeshLog, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
640
144
    create_stub_boot_type(tc, MVM_REPR_ID_MVMStaticFrameSpesh, StaticFrameSpesh, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
641
144
642
144
    /* Bootstrap the KnowHOW type, giving it a meta-object. */
643
144
    bootstrap_KnowHOW(tc);
644
144
645
144
    /* Give stub types meta-objects. */
646
3.45k
#define meta_objectifier(tc, slot, name) do { \
647
3.45k
    add_meta_object((tc), (tc)->instance->slot, (name)); \
648
3.45k
    MVM_gc_root_add_permanent_desc((tc), (MVMCollectable **)&(tc)->instance->slot, name); \
649
3.45k
} while (0)
650
144
    meta_objectifier(tc, VMString, "VMString");
651
144
    meta_objectifier(tc, VMNull, "VMNull");
652
144
    meta_objectifier(tc, boot_types.BOOTInt, "BOOTInt");
653
144
    meta_objectifier(tc, boot_types.BOOTNum, "BOOTNum");
654
144
    meta_objectifier(tc, boot_types.BOOTStr, "BOOTStr");
655
144
    meta_objectifier(tc, boot_types.BOOTArray, "BOOTArray");
656
144
    meta_objectifier(tc, boot_types.BOOTHash, "BOOTHash");
657
144
    meta_objectifier(tc, boot_types.BOOTCCode, "BOOTCCode");
658
144
    meta_objectifier(tc, boot_types.BOOTCode, "BOOTCode");
659
144
    meta_objectifier(tc, boot_types.BOOTThread, "BOOTThread");
660
144
    meta_objectifier(tc, boot_types.BOOTIter, "BOOTIter");
661
144
    meta_objectifier(tc, boot_types.BOOTContext, "BOOTContext");
662
144
    meta_objectifier(tc, SCRef, "SCRef");
663
144
    meta_objectifier(tc, CallCapture, "CallCapture");
664
144
    meta_objectifier(tc, boot_types.BOOTIO, "BOOTIO");
665
144
    meta_objectifier(tc, boot_types.BOOTException, "BOOTException");
666
144
    meta_objectifier(tc, boot_types.BOOTStaticFrame, "BOOTStaticFrame");
667
144
    meta_objectifier(tc, boot_types.BOOTCompUnit, "BOOTCompUnit");
668
144
    meta_objectifier(tc, boot_types.BOOTMultiCache, "BOOTMultiCache");
669
144
    meta_objectifier(tc, boot_types.BOOTContinuation, "BOOTContinuation");
670
144
    meta_objectifier(tc, Thread, "Thread");
671
144
    meta_objectifier(tc, boot_types.BOOTQueue, "BOOTQueue");
672
144
    meta_objectifier(tc, boot_types.BOOTAsync, "BOOTAsync");
673
144
    meta_objectifier(tc, boot_types.BOOTReentrantMutex, "BOOTReentrantMutex");
674
144
675
144
    /* Create the KnowHOWAttribute type. */
676
144
    create_KnowHOWAttribute(tc);
677
144
678
144
    /* Bootstrap typed arrays. */
679
144
    tc->instance->boot_types.BOOTIntArray = boot_typed_array(tc, "BOOTIntArray",
680
144
        tc->instance->boot_types.BOOTInt);
681
144
    MVM_gc_root_add_permanent_desc(tc,
682
144
        (MVMCollectable **)&tc->instance->boot_types.BOOTIntArray,
683
144
        "BOOTIntArray");
684
144
    tc->instance->boot_types.BOOTNumArray = boot_typed_array(tc, "BOOTNumArray",
685
144
        tc->instance->boot_types.BOOTNum);
686
144
    MVM_gc_root_add_permanent_desc(tc,
687
144
        (MVMCollectable **)&tc->instance->boot_types.BOOTNumArray,
688
144
        "BOOTNumArray");
689
144
    tc->instance->boot_types.BOOTStrArray = boot_typed_array(tc, "BOOTStrArray",
690
144
        tc->instance->boot_types.BOOTStr);
691
144
    MVM_gc_root_add_permanent_desc(tc,
692
144
        (MVMCollectable **)&tc->instance->boot_types.BOOTStrArray,
693
144
        "BOOTStrArray");
694
144
695
144
    /* Set up HLL roles. */
696
144
    STABLE(tc->instance->boot_types.BOOTInt)->hll_role   = MVM_HLL_ROLE_INT;
697
144
    STABLE(tc->instance->boot_types.BOOTNum)->hll_role   = MVM_HLL_ROLE_NUM;
698
144
    STABLE(tc->instance->boot_types.BOOTStr)->hll_role   = MVM_HLL_ROLE_STR;
699
144
    STABLE(tc->instance->boot_types.BOOTArray)->hll_role = MVM_HLL_ROLE_ARRAY;
700
144
    STABLE(tc->instance->boot_types.BOOTHash)->hll_role  = MVM_HLL_ROLE_HASH;
701
144
    STABLE(tc->instance->boot_types.BOOTCode)->hll_role  = MVM_HLL_ROLE_CODE;
702
144
703
144
    /* Get initial __6MODEL_CORE__ serialization context set up. */
704
144
    setup_core_sc(tc);
705
144
    MVM_6model_containers_setup(tc);
706
144
707
144
    MVM_intcache_for(tc, tc->instance->boot_types.BOOTInt);
708
144
}