/home/travis/build/MoarVM/MoarVM/src/6model/reprs.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "moar.h" |
2 | | #include "gcc_diag.h" |
3 | | |
4 | | /* Default REPR function handlers. */ |
5 | | GCC_DIAG_OFF(return-type) |
6 | 0 | MVMuint64 MVM_REPR_DEFAULT_ELEMS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { |
7 | 0 | MVM_exception_throw_adhoc(tc, |
8 | 0 | "This representation (%s) does not support elems (for type %s)", |
9 | 0 | st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
10 | 0 | } |
11 | | GCC_DIAG_ON(return-type) |
12 | | MVM_NO_RETURN static void die_no_attrs(MVMThreadContext *tc, const char *repr_name, const char *debug_name) MVM_NO_RETURN_ATTRIBUTE; |
13 | 0 | static void die_no_attrs(MVMThreadContext *tc, const char *repr_name, const char *debug_name) { |
14 | 0 | MVM_exception_throw_adhoc(tc, |
15 | 0 | "This representation (%s) does not support attribute storage (for type %s)", repr_name, debug_name); |
16 | 0 | } |
17 | 0 | void MVM_REPR_DEFAULT_GET_ATTRIBUTE(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *class_handle, MVMString *name, MVMint64 hint, MVMRegister *result, MVMuint16 kind) { |
18 | 0 | die_no_attrs(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
19 | 0 | } |
20 | 0 | void MVM_REPR_DEFAULT_BIND_ATTRIBUTE(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *class_handle, MVMString *name, MVMint64 hint, MVMRegister value, MVMuint16 kind) { |
21 | 0 | die_no_attrs(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
22 | 0 | } |
23 | | GCC_DIAG_OFF(return-type) |
24 | 0 | MVMint64 MVM_REPR_DEFAULT_IS_ATTRIBUTE_INITIALIZED(MVMThreadContext *tc, MVMSTable *st, void *data, MVMObject *class_handle, MVMString *name, MVMint64 hint) { |
25 | 0 | die_no_attrs(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
26 | 0 | } |
27 | 0 | AO_t * MVM_REPR_DEFAULT_ATTRIBUTE_AS_ATOMIC(MVMThreadContext *tc, MVMSTable *st, void *data, MVMObject *class_handle, MVMString *name, MVMuint16 kind) { |
28 | 0 | die_no_attrs(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
29 | 0 | } |
30 | | GCC_DIAG_ON(return-type) |
31 | 0 | MVMint64 MVM_REPR_DEFAULT_HINT_FOR(MVMThreadContext *tc, MVMSTable *st, MVMObject *class_handle, MVMString *name) { |
32 | 0 | return MVM_NO_HINT; |
33 | 0 | } |
34 | 0 | void MVM_REPR_DEFAULT_SET_INT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 value) { |
35 | 0 | MVM_exception_throw_adhoc(tc, |
36 | 0 | "This representation (%s) cannot box a native int (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
37 | 0 | } |
38 | 5 | MVMint64 MVM_REPR_DEFAULT_GET_INT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { |
39 | 5 | MVM_exception_throw_adhoc(tc, |
40 | 5 | "This representation (%s) cannot unbox to a native int (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
41 | 5 | } |
42 | 0 | void MVM_REPR_DEFAULT_SET_NUM(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMnum64 value) { |
43 | 0 | MVM_exception_throw_adhoc(tc, |
44 | 0 | "This representation (%s) cannot box a native num (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
45 | 0 | } |
46 | 5 | MVMnum64 MVM_REPR_DEFAULT_GET_NUM(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { |
47 | 5 | MVM_exception_throw_adhoc(tc, |
48 | 5 | "This representation (%s) cannot unbox to a native num (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
49 | 5 | } |
50 | 0 | void MVM_REPR_DEFAULT_SET_STR(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMString *value) { |
51 | 0 | MVM_exception_throw_adhoc(tc, |
52 | 0 | "This representation (%s) cannot box a native string (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
53 | 0 | } |
54 | 5 | MVMString * MVM_REPR_DEFAULT_GET_STR(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { |
55 | 5 | MVM_exception_throw_adhoc(tc, |
56 | 5 | "This representation (%s) cannot unbox to a native string (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
57 | 5 | } |
58 | 0 | void MVM_REPR_DEFAULT_SET_UINT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMuint64 value) { |
59 | 0 | MVM_exception_throw_adhoc(tc, |
60 | 0 | "This representation (%s) cannot box an unsigned native int (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
61 | 0 | } |
62 | 0 | MVMuint64 MVM_REPR_DEFAULT_GET_UINT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { |
63 | 0 | MVM_exception_throw_adhoc(tc, |
64 | 0 | "This representation (%s) cannot unbox to an unsigned native int (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
65 | 0 | } |
66 | 0 | void * MVM_REPR_DEFAULT_GET_BOXED_REF(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMuint32 repr_id) { |
67 | 0 | MVM_exception_throw_adhoc(tc, |
68 | 0 | "This representation (%s) cannot unbox to other types (for type %s)", st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
69 | 0 | } |
70 | | MVM_NO_RETURN static void die_no_pos(MVMThreadContext *tc, const char *repr_name, const char *debug_name) MVM_NO_RETURN_ATTRIBUTE; |
71 | 0 | static void die_no_pos(MVMThreadContext *tc, const char *repr_name, const char *debug_name) { |
72 | 0 | MVM_exception_throw_adhoc(tc, |
73 | 0 | "This representation (%s) does not support positional access (for type %s)", repr_name, debug_name); |
74 | 0 | } |
75 | 0 | void MVM_REPR_DEFAULT_AT_POS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind) { |
76 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
77 | 0 | } |
78 | 0 | void MVM_REPR_DEFAULT_BIND_POS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister value, MVMuint16 kind) { |
79 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
80 | 0 | } |
81 | 0 | void MVM_REPR_DEFAULT_SET_ELEMS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMuint64 count) { |
82 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
83 | 0 | } |
84 | 0 | void MVM_REPR_DEFAULT_PUSH(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister value, MVMuint16 kind) { |
85 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
86 | 0 | } |
87 | 0 | void MVM_REPR_DEFAULT_POP(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind) { |
88 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
89 | 0 | } |
90 | 0 | void MVM_REPR_DEFAULT_UNSHIFT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister value, MVMuint16 kind) { |
91 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
92 | 0 | } |
93 | 0 | void MVM_REPR_DEFAULT_SHIFT(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind) { |
94 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
95 | 0 | } |
96 | 0 | void MVM_REPR_DEFAULT_SLICE(MVMThreadContext *tc, MVMSTable *st, MVMObject *src, void *data, MVMObject *dest, MVMint64 start, MVMint64 end) { |
97 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
98 | 0 | } |
99 | 0 | void MVM_REPR_DEFAULT_AT_POS_MULTIDIM(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 num_indices, MVMint64 *indices, MVMRegister *value, MVMuint16 kind) { |
100 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
101 | 0 | } |
102 | 0 | void MVM_REPR_DEFAULT_BIND_POS_MULTIDIM(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 num_indices, MVMint64 *indices, MVMRegister value, MVMuint16 kind) { |
103 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
104 | 0 | } |
105 | 0 | void MVM_REPR_DEFAULT_DIMENSIONS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 *num_dimensions, MVMint64 **dimensions) { |
106 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
107 | 0 | } |
108 | 0 | void MVM_REPR_DEFAULT_SET_DIMENSIONS(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 num_dimensions, MVMint64 *dimensions) { |
109 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
110 | 0 | } |
111 | | GCC_DIAG_OFF(return-type) |
112 | 0 | MVMStorageSpec MVM_REPR_DEFAULT_GET_ELEM_STORAGE_SPEC(MVMThreadContext *tc, MVMSTable *st) { |
113 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
114 | 0 | } |
115 | | AO_t * MVM_REPR_DEFAULT_POS_AS_ATOMIC(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, |
116 | 0 | void *data, MVMint64 index) { |
117 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
118 | 0 | } |
119 | | AO_t * MVM_REPR_DEFAULT_POS_AS_ATOMIC_MULTIDIM(MVMThreadContext *tc, MVMSTable *st, |
120 | | MVMObject *root, void *data, |
121 | 0 | MVMint64 num_indices, MVMint64 *indices) { |
122 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
123 | 0 | } |
124 | | GCC_DIAG_ON(return-type) |
125 | 0 | void MVM_REPR_DEFAULT_SPLICE(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *target_array, MVMint64 offset, MVMuint64 elems) { |
126 | 0 | die_no_pos(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
127 | 0 | } |
128 | | MVM_NO_RETURN static void die_no_ass(MVMThreadContext *tc, const char *repr_name, const char *debug_name) MVM_NO_RETURN_ATTRIBUTE; |
129 | 0 | static void die_no_ass(MVMThreadContext *tc, const char *repr_name, const char *debug_name) { |
130 | 0 | MVM_exception_throw_adhoc(tc, |
131 | 0 | "This representation (%s) does not support associative access (for type %s)", repr_name, debug_name); |
132 | 0 | } |
133 | 0 | void MVM_REPR_DEFAULT_AT_KEY(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister *result, MVMuint16 kind) { |
134 | 0 | die_no_ass(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
135 | 0 | } |
136 | 0 | void MVM_REPR_DEFAULT_BIND_KEY(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister value, MVMuint16 kind) { |
137 | 0 | die_no_ass(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
138 | 0 | } |
139 | | GCC_DIAG_OFF(return-type) |
140 | 0 | MVMint64 MVM_REPR_DEFAULT_EXISTS_KEY(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) { |
141 | 0 | die_no_ass(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
142 | 0 | } |
143 | | GCC_DIAG_ON(return-type) |
144 | 0 | void MVM_REPR_DEFAULT_DELETE_KEY(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) { |
145 | 0 | die_no_ass(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
146 | 0 | } |
147 | | GCC_DIAG_OFF(return-type) |
148 | 0 | MVMStorageSpec MVM_REPR_DEFAULT_GET_VALUE_STORAGE_SPEC(MVMThreadContext *tc, MVMSTable *st) { |
149 | 0 | die_no_ass(tc, st->REPR->name, MVM_6model_get_stable_debug_name(tc, st)); |
150 | 0 | } |
151 | | GCC_DIAG_ON(return-type) |
152 | | |
153 | | /* Registers a representation. */ |
154 | 6.48k | static void register_repr(MVMThreadContext *tc, const MVMREPROps *repr, MVMString *name) { |
155 | 6.48k | MVMReprRegistry *entry; |
156 | 6.48k | |
157 | 6.48k | if (!name) |
158 | 6.48k | name = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, |
159 | 6.48k | repr->name); |
160 | 6.48k | |
161 | 6.48k | /* Fill a registry entry. */ |
162 | 6.48k | entry = MVM_malloc(sizeof(MVMReprRegistry)); |
163 | 6.48k | entry->name = name; |
164 | 6.48k | entry->repr = repr; |
165 | 6.48k | |
166 | 6.48k | /* Enter into registry. */ |
167 | 6.48k | tc->instance->repr_list[repr->ID] = entry; |
168 | 6.48k | MVM_HASH_BIND(tc, tc->instance->repr_hash, name, entry); |
169 | 6.48k | |
170 | 6.48k | /* Name and hash key should become a permanent GC root. */ |
171 | 6.48k | MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&entry->name, "REPR name"); |
172 | 6.48k | MVM_gc_root_add_permanent_desc(tc, (MVMCollectable **)&entry->hash_handle.key, |
173 | 6.48k | "REPR registry hash key"); |
174 | 6.48k | } |
175 | | |
176 | 0 | int MVM_repr_register_dynamic_repr(MVMThreadContext *tc, MVMREPROps *repr) { |
177 | 0 | MVMReprRegistry *entry; |
178 | 0 | MVMString *name; |
179 | 0 |
|
180 | 0 | uv_mutex_lock(&tc->instance->mutex_repr_registry); |
181 | 0 |
|
182 | 0 | name = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, repr->name); |
183 | 0 | MVM_HASH_GET(tc, tc->instance->repr_hash, name, entry); |
184 | 0 | if (entry) { |
185 | 0 | uv_mutex_unlock(&tc->instance->mutex_repr_registry); |
186 | 0 | return 0; |
187 | 0 | } |
188 | 0 |
|
189 | 0 | if (!(tc->instance->num_reprs < MVM_REPR_MAX_COUNT)) { |
190 | 0 | uv_mutex_unlock(&tc->instance->mutex_repr_registry); |
191 | 0 | MVM_exception_throw_adhoc(tc, |
192 | 0 | "Cannot register more than %u representations", |
193 | 0 | MVM_REPR_MAX_COUNT); |
194 | 0 | } |
195 | 0 |
|
196 | 0 | repr->ID = tc->instance->num_reprs++; |
197 | 0 | register_repr(tc, repr, name); |
198 | 0 |
|
199 | 0 | uv_mutex_unlock(&tc->instance->mutex_repr_registry); |
200 | 0 | return 1; |
201 | 0 | } |
202 | | |
203 | | #define register_core_repr(name) \ |
204 | 6.48k | register_repr(tc, MVM##name##_initialize(tc), NULL) |
205 | | |
206 | | /* Initializes the representations registry, building up all of the various |
207 | | * representations. */ |
208 | 144 | void MVM_repr_initialize_registry(MVMThreadContext *tc) { |
209 | 144 | tc->instance->repr_list = MVM_malloc( |
210 | 144 | MVM_REPR_MAX_COUNT * sizeof *tc->instance->repr_list); |
211 | 144 | |
212 | 144 | /* Add all core representations. */ |
213 | 144 | register_core_repr(String); |
214 | 144 | register_core_repr(Array); |
215 | 144 | register_core_repr(Hash); |
216 | 144 | register_core_repr(CFunction); |
217 | 144 | register_core_repr(KnowHOWREPR); |
218 | 144 | register_core_repr(P6opaque); |
219 | 144 | register_core_repr(Code); |
220 | 144 | register_core_repr(OSHandle); |
221 | 144 | register_core_repr(P6int); |
222 | 144 | register_core_repr(P6num); |
223 | 144 | register_core_repr(Uninstantiable); |
224 | 144 | register_core_repr(HashAttrStore); |
225 | 144 | register_core_repr(KnowHOWAttributeREPR); |
226 | 144 | register_core_repr(P6str); |
227 | 144 | register_core_repr(Thread); |
228 | 144 | register_core_repr(Iter); |
229 | 144 | register_core_repr(Context); |
230 | 144 | register_core_repr(SCRef); |
231 | 144 | register_core_repr(CallCapture); |
232 | 144 | register_core_repr(P6bigint); |
233 | 144 | register_core_repr(NFA); |
234 | 144 | register_core_repr(Exception); |
235 | 144 | register_core_repr(StaticFrame); |
236 | 144 | register_core_repr(CompUnit); |
237 | 144 | register_core_repr(DLLSym); |
238 | 144 | register_core_repr(MultiCache); |
239 | 144 | register_core_repr(Continuation); |
240 | 144 | register_core_repr(NativeCall); |
241 | 144 | register_core_repr(CPointer); |
242 | 144 | register_core_repr(CStr); |
243 | 144 | register_core_repr(CArray); |
244 | 144 | register_core_repr(CStruct); |
245 | 144 | register_core_repr(CUnion); |
246 | 144 | register_core_repr(ReentrantMutex); |
247 | 144 | register_core_repr(ConditionVariable); |
248 | 144 | register_core_repr(Semaphore); |
249 | 144 | register_core_repr(ConcBlockingQueue); |
250 | 144 | register_core_repr(AsyncTask); |
251 | 144 | register_core_repr(Null); |
252 | 144 | register_core_repr(CPPStruct); |
253 | 144 | register_core_repr(NativeRef); |
254 | 144 | register_core_repr(MultiDimArray); |
255 | 144 | register_core_repr(Decoder); |
256 | 144 | register_core_repr(SpeshLog); |
257 | 144 | register_core_repr(StaticFrameSpesh); |
258 | 144 | |
259 | 144 | tc->instance->num_reprs = MVM_REPR_CORE_COUNT; |
260 | 144 | } |
261 | | |
262 | | static MVMReprRegistry * find_repr_by_name(MVMThreadContext *tc, |
263 | 27.6k | MVMString *name) { |
264 | 27.6k | MVMReprRegistry *entry; |
265 | 27.6k | |
266 | 27.6k | MVM_HASH_GET(tc, tc->instance->repr_hash, name, entry) |
267 | 27.6k | |
268 | 27.6k | if (entry == NULL) { |
269 | 0 | char *c_name = MVM_string_ascii_encode_any(tc, name); |
270 | 0 | char *waste[] = { c_name, NULL }; |
271 | 0 | MVM_exception_throw_adhoc_free(tc, waste, "Lookup by name of unknown REPR: %s", |
272 | 0 | c_name); |
273 | 0 | } |
274 | 27.6k | |
275 | 27.6k | return entry; |
276 | 27.6k | } |
277 | | |
278 | | /* Get a representation's ID from its name. Note that the IDs may change so |
279 | | * it's best not to store references to them in e.g. the bytecode stream. */ |
280 | 0 | MVMuint32 MVM_repr_name_to_id(MVMThreadContext *tc, MVMString *name) { |
281 | 0 | return find_repr_by_name(tc, name)->repr->ID; |
282 | 0 | } |
283 | | |
284 | | /* Gets a representation by ID. */ |
285 | 4.32k | const MVMREPROps * MVM_repr_get_by_id(MVMThreadContext *tc, MVMuint32 id) { |
286 | 4.32k | if (id >= tc->instance->num_reprs) |
287 | 0 | MVM_exception_throw_adhoc(tc, "REPR lookup by invalid ID %" PRIu32, id); |
288 | 4.32k | |
289 | 4.32k | return tc->instance->repr_list[id]->repr; |
290 | 4.32k | } |
291 | | |
292 | | /* Gets a representation by name. */ |
293 | 27.6k | const MVMREPROps * MVM_repr_get_by_name(MVMThreadContext *tc, MVMString *name) { |
294 | 27.6k | return find_repr_by_name(tc, name)->repr; |
295 | 27.6k | } |