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