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