1 #include "ml_gir.h"
2 #include "ml_macros.h"
3 #include <gc/gc.h>
4 #include <girffi.h>
5 #include <stdio.h>
6 
7 //!gir
8 
9 typedef struct typelib_t {
10 	ml_type_t *Type;
11 	GITypelib *Handle;
12 	const char *Namespace;
13 } typelib_t;
14 
15 ML_TYPE(TypelibT, (MLIteratableT), "gir-typelib");
16 //@gir-typelib
17 // A gobject-introspection typelib.
18 
19 typedef struct typelib_iter_t {
20 	ml_type_t *Type;
21 	GITypelib *Handle;
22 	const char *Namespace;
23 	GIBaseInfo *Current;
24 	int Index, Total;
25 } typelib_iter_t;
26 
27 typedef struct {
28 	ml_type_t *Type;
29 	GIBaseInfo *Info;
30 } baseinfo_t;
31 
32 ML_TYPE(BaseInfoT, (MLTypeT), "gir-base-info");
33 
34 static ml_value_t *baseinfo_to_value(GIBaseInfo *Info);
35 static void _ml_to_value(ml_value_t *Source, GValue *Dest);
36 static ml_value_t *_value_to_ml(const GValue *Value, GIBaseInfo *Info);
37 
typelib_iter_value(ml_state_t * Caller,typelib_iter_t * Iter)38 static void typelib_iter_value(ml_state_t *Caller, typelib_iter_t *Iter) {
39 	const char *Type = g_info_type_to_string(g_base_info_get_type(Iter->Current));
40 	ML_CONTINUE(Caller, ml_string(Type, -1));
41 }
42 
typelib_iter_next(ml_state_t * Caller,typelib_iter_t * Iter)43 static void typelib_iter_next(ml_state_t *Caller, typelib_iter_t *Iter) {
44 	if (++Iter->Index >= Iter->Total) ML_CONTINUE(Caller, MLNil);
45 	Iter->Current = g_irepository_get_info(NULL, Iter->Namespace, Iter->Index);
46 	ML_CONTINUE(Caller, Iter);
47 }
48 
typelib_iter_key(ml_state_t * Caller,typelib_iter_t * Iter)49 static void typelib_iter_key(ml_state_t *Caller, typelib_iter_t *Iter) {
50 	ML_CONTINUE(Caller, ml_string(g_base_info_get_name(Iter->Current), -1));
51 }
52 
53 ML_TYPE(TypelibIterT, (), "typelib-iter");
54 //!internal
55 
ML_FUNCTION(MLGir)56 ML_FUNCTION(MLGir) {
57 //@gir
58 //<Name:string
59 //>gir-typelib
60 	ML_CHECK_ARG_COUNT(1);
61 	ML_CHECK_ARG_TYPE(0, MLStringT);
62 	typelib_t *Typelib = new(typelib_t);
63 	Typelib->Type = TypelibT;
64 	GError *Error = 0;
65 	Typelib->Namespace = ml_string_value(Args[0]);
66 	const char *Version = NULL;
67 	if (Count > 1) {
68 		ML_CHECK_ARG_TYPE(1, MLStringT);
69 		Version = ml_string_value(Args[1]);
70 	}
71 	Typelib->Handle = g_irepository_require(NULL, Typelib->Namespace, Version, 0, &Error);
72 	if (!Typelib->Handle) return ml_error("GirError", Error->message);
73 	return (ml_value_t *)Typelib;
74 }
75 
76 typedef struct object_t {
77 	ml_type_t Base;
78 	GIObjectInfo *Info;
79 	stringmap_t Signals[1];
80 } object_t;
81 
82 typedef struct object_instance_t {
83 	const object_t *Type;
84 	void *Handle;
85 } object_instance_t;
86 
87 ML_TYPE(ObjectT, (BaseInfoT), "gir-object-type");
88 // A gobject-introspection object type.
89 
90 ML_TYPE(ObjectInstanceT, (), "gir-object");
91 // A gobject-introspection object instance.
92 
93 static object_instance_t *ObjectInstanceNil;
94 
95 static ml_type_t *object_info_lookup(GIObjectInfo *Info);
96 static ml_type_t *interface_info_lookup(GIInterfaceInfo *Info);
97 static ml_type_t *struct_info_lookup(GIStructInfo *Info);
98 static ml_type_t *enum_info_lookup(GIEnumInfo *Info);
99 
instance_finalize(object_instance_t * Instance,void * Data)100 static void instance_finalize(object_instance_t *Instance, void *Data) {
101 	g_object_unref(Instance->Handle);
102 }
103 
104 static GQuark MLQuark;
105 
ml_gir_instance_get(void * Handle,GIBaseInfo * Fallback)106 ml_value_t *ml_gir_instance_get(void *Handle, GIBaseInfo *Fallback) {
107 	if (Handle == 0) return (ml_value_t *)ObjectInstanceNil;
108 	object_instance_t *Instance = (object_instance_t *)g_object_get_qdata(Handle, MLQuark);
109 	if (Instance) return (ml_value_t *)Instance;
110 	Instance = new(object_instance_t);
111 	Instance->Handle = Handle;
112 	g_object_ref_sink(Handle);
113 	GC_register_finalizer(Instance, (GC_finalization_proc)instance_finalize, 0, 0, 0);
114 	GType Type = G_OBJECT_TYPE(Handle);
115 	GIBaseInfo *Info = g_irepository_find_by_gtype(NULL, Type);
116 	if (Info) {
117 		switch (g_base_info_get_type(Info)) {
118 		case GI_INFO_TYPE_OBJECT: {
119 			Instance->Type = (object_t *)object_info_lookup((GIObjectInfo *)Info);
120 			break;
121 		}
122 		case GI_INFO_TYPE_INTERFACE: {
123 			Instance->Type = (object_t *)interface_info_lookup((GIInterfaceInfo *)Info);
124 			break;
125 		}
126 		default: {
127 			return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(Info), __LINE__);
128 		}
129 		}
130 		g_object_set_qdata(Handle, MLQuark, Instance);
131 	} else if (Fallback) {
132 		switch (g_base_info_get_type(Fallback)) {
133 		case GI_INFO_TYPE_OBJECT: {
134 			Instance->Type = (object_t *)object_info_lookup((GIObjectInfo *)Fallback);
135 			break;
136 		}
137 		case GI_INFO_TYPE_INTERFACE: {
138 			Instance->Type = (object_t *)interface_info_lookup((GIInterfaceInfo *)Fallback);
139 			break;
140 		}
141 		default: {
142 			return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(Fallback), __LINE__);
143 		}
144 		}
145 	} else {
146 		return ml_error("UnknownType", "Type %s not found", g_type_name(Type));
147 	}
148 	return (ml_value_t *)Instance;
149 }
150 
ML_METHOD(MLStringT,ObjectInstanceT)151 ML_METHOD(MLStringT, ObjectInstanceT) {
152 //<Object
153 //>string
154 	object_instance_t *Instance = (object_instance_t *)Args[0];
155 	if (Instance == ObjectInstanceNil) {
156 		return ml_cstring("(null)");
157 	} else {
158 		return ml_string_format("<%s>", g_base_info_get_name((GIBaseInfo *)Instance->Type->Info));
159 	}
160 }
161 
162 typedef struct struct_t {
163 	ml_type_t Base;
164 	GIStructInfo *Info;
165 } struct_t;
166 
167 typedef struct struct_instance_t {
168 	const struct_t *Type;
169 	void *Value;
170 } struct_instance_t;
171 
172 ML_TYPE(StructT, (BaseInfoT), "gir-struct-type");
173 // A gobject-introspection struct type.
174 
175 ML_TYPE(StructInstanceT, (), "gir-struct");
176 // A gobject-introspection struct instance.
177 
struct_instance_new(struct_t * Struct,int Count,ml_value_t ** Args)178 static ml_value_t *struct_instance_new(struct_t *Struct, int Count, ml_value_t **Args) {
179 	struct_instance_t *Instance = new(struct_instance_t);
180 	Instance->Type = Struct;
181 	Instance->Value = GC_MALLOC(g_struct_info_get_size(Struct->Info));
182 	return (ml_value_t *)Instance;
183 }
184 
ML_METHOD(MLStringT,StructInstanceT)185 ML_METHOD(MLStringT, StructInstanceT) {
186 //<Struct
187 //>string
188 	struct_instance_t *Instance = (struct_instance_t *)Args[0];
189 	return ml_string_format("<%s>", g_base_info_get_name((GIBaseInfo *)Instance->Type->Info));
190 }
191 
192 typedef struct field_ref_t {
193 	ml_type_t *Type;
194 	void *Address;
195 } field_ref_t;
196 
197 #define FIELD_REF(UNAME, LNAME, GTYPE, GETTER, SETTER) \
198 static ml_value_t *field_ref_ ## LNAME ## _deref(field_ref_t *Ref) { \
199 	GTYPE Value = *(GTYPE *)Ref->Address; \
200 	return GETTER; \
201 } \
202 \
203 static ml_value_t *field_ref_ ## LNAME ## _assign(field_ref_t *Ref, ml_value_t *Value) { \
204 	GTYPE *Address = (GTYPE *)Ref->Address; \
205 	*Address = SETTER; \
206 	return Value; \
207 } \
208 \
209 ML_TYPE(FieldRef ## UNAME ## T, (), "field-ref-" #LNAME, \
210 	.deref = (void *)field_ref_ ## LNAME ## _deref, \
211 	.assign = (void *)field_ref_ ## LNAME ## _assign \
212 );
213 
214 FIELD_REF(Boolean, boolean, gboolean, ml_boolean(Value), ml_boolean_value(Value));
215 FIELD_REF(Int8, int8, gint8, ml_integer(Value), ml_integer_value(Value));
216 FIELD_REF(UInt8, uint8, guint8, ml_integer(Value), ml_integer_value(Value));
217 FIELD_REF(Int16, int16, gint16, ml_integer(Value), ml_integer_value(Value));
218 FIELD_REF(UInt16, uint16, guint16, ml_integer(Value), ml_integer_value(Value));
219 FIELD_REF(Int32, int32, gint32, ml_integer(Value), ml_integer_value(Value));
220 FIELD_REF(UInt32, uint32, guint32, ml_integer(Value), ml_integer_value(Value));
221 FIELD_REF(Int64, int64, gint64, ml_integer(Value), ml_integer_value(Value));
222 FIELD_REF(UInt64, uint64, guint64, ml_integer(Value), ml_integer_value(Value));
223 FIELD_REF(Float, float, gfloat, ml_real(Value), ml_real_value(Value));
224 FIELD_REF(Double, double, gdouble, ml_real(Value), ml_real_value(Value));
225 FIELD_REF(Utf8, utf8, gchar *, ml_string(Value, -1), (char *)ml_string_value(Value));
226 
struct_field_ref(GIFieldInfo * Info,int Count,ml_value_t ** Args)227 static ml_value_t *struct_field_ref(GIFieldInfo *Info, int Count, ml_value_t **Args) {
228 	struct_instance_t *Instance = (struct_instance_t *)Args[0];
229 	field_ref_t *Ref = new(field_ref_t);
230 	Ref->Address = (char *)Instance->Value + g_field_info_get_offset(Info);
231 	GITypeInfo *TypeInfo = g_field_info_get_type(Info);
232 	switch (g_type_info_get_tag(TypeInfo)) {
233 	case GI_TYPE_TAG_VOID: return ml_error("TodoError", "Field ref not implemented yet");
234 	case GI_TYPE_TAG_BOOLEAN: Ref->Type = FieldRefBooleanT; break;
235 	case GI_TYPE_TAG_INT8: Ref->Type = FieldRefInt8T; break;
236 	case GI_TYPE_TAG_UINT8: Ref->Type = FieldRefUInt8T; break;
237 	case GI_TYPE_TAG_INT16: Ref->Type = FieldRefInt16T; break;
238 	case GI_TYPE_TAG_UINT16: Ref->Type = FieldRefUInt16T; break;
239 	case GI_TYPE_TAG_INT32: Ref->Type = FieldRefInt32T; break;
240 	case GI_TYPE_TAG_UINT32: Ref->Type = FieldRefUInt32T; break;
241 	case GI_TYPE_TAG_INT64: Ref->Type = FieldRefInt64T; break;
242 	case GI_TYPE_TAG_UINT64: Ref->Type = FieldRefUInt64T; break;
243 	case GI_TYPE_TAG_FLOAT: Ref->Type = FieldRefFloatT; break;
244 	case GI_TYPE_TAG_DOUBLE: Ref->Type = FieldRefDoubleT; break;
245 	case GI_TYPE_TAG_GTYPE: return ml_error("TodoError", "Field ref not implemented yet");
246 	case GI_TYPE_TAG_UTF8: Ref->Type = FieldRefUtf8T; break;
247 	case GI_TYPE_TAG_FILENAME: Ref->Type = FieldRefUtf8T; break;
248 	case GI_TYPE_TAG_ARRAY: return ml_error("TodoError", "Field ref not implemented yet");
249 	case GI_TYPE_TAG_INTERFACE: {
250 		GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
251 		switch (g_base_info_get_type(InterfaceInfo)) {
252 		case GI_INFO_TYPE_INVALID:
253 		case GI_INFO_TYPE_INVALID_0: return ml_error("TodoError", "Field ref not implemented yet");
254 		case GI_INFO_TYPE_FUNCTION: return ml_error("TodoError", "Field ref not implemented yet");
255 		case GI_INFO_TYPE_CALLBACK: return ml_error("TodoError", "Field ref not implemented yet");
256 		case GI_INFO_TYPE_STRUCT: return ml_error("TodoError", "Field ref not implemented yet");
257 		case GI_INFO_TYPE_BOXED: return ml_error("TodoError", "Field ref not implemented yet");
258 		case GI_INFO_TYPE_ENUM: return ml_error("TodoError", "Field ref not implemented yet");
259 		case GI_INFO_TYPE_FLAGS: return ml_error("TodoError", "Field ref not implemented yet");
260 		case GI_INFO_TYPE_OBJECT: return ml_error("TodoError", "Field ref not implemented yet");
261 		case GI_INFO_TYPE_INTERFACE: return ml_error("TodoError", "Field ref not implemented yet");
262 		case GI_INFO_TYPE_CONSTANT: return ml_error("TodoError", "Field ref not implemented yet");
263 		case GI_INFO_TYPE_UNION: return ml_error("TodoError", "Field ref not implemented yet");
264 		case GI_INFO_TYPE_VALUE: return ml_error("TodoError", "Field ref not implemented yet");
265 		case GI_INFO_TYPE_SIGNAL: return ml_error("TodoError", "Field ref not implemented yet");
266 		case GI_INFO_TYPE_VFUNC: return ml_error("TodoError", "Field ref not implemented yet");
267 		case GI_INFO_TYPE_PROPERTY: return ml_error("TodoError", "Field ref not implemented yet");
268 		case GI_INFO_TYPE_FIELD: return ml_error("TodoError", "Field ref not implemented yet");
269 		case GI_INFO_TYPE_ARG: return ml_error("TodoError", "Field ref not implemented yet");
270 		case GI_INFO_TYPE_TYPE: return ml_error("TodoError", "Field ref not implemented yet");
271 		case GI_INFO_TYPE_UNRESOLVED: return ml_error("TodoError", "Field ref not implemented yet");
272 		}
273 		break;
274 	}
275 	case GI_TYPE_TAG_GLIST: return ml_error("TodoError", "Field ref not implemented yet");
276 	case GI_TYPE_TAG_GSLIST: return ml_error("TodoError", "Field ref not implemented yet");
277 	case GI_TYPE_TAG_GHASH: return ml_error("TodoError", "Field ref not implemented yet");
278 	case GI_TYPE_TAG_ERROR: return ml_error("TodoError", "Field ref not implemented yet");
279 	case GI_TYPE_TAG_UNICHAR: return ml_error("TodoError", "Field ref not implemented yet");
280 	}
281 	return (ml_value_t *)Ref;
282 }
283 
284 typedef struct enum_t {
285 	ml_type_t Base;
286 	GIEnumInfo *Info;
287 	ml_value_t *ByIndex[];
288 } enum_t;
289 
290 typedef struct enum_value_t {
291 	const enum_t *Type;
292 	ml_value_t *Name;
293 	gint64 Value;
294 } enum_value_t;
295 
296 ML_TYPE(EnumT, (BaseInfoT), "gir-enum-type");
297 // A gobject-instrospection enum type.
298 
299 ML_TYPE(EnumValueT, (), "gir-enum");
300 // A gobject-instrospection enum value.
301 
ML_METHOD(MLStringT,EnumValueT)302 ML_METHOD(MLStringT, EnumValueT) {
303 //<Value
304 //>string
305 	enum_value_t *Value = (enum_value_t *)Args[0];
306 	return Value->Name;
307 }
308 
ML_METHOD(MLIntegerT,EnumValueT)309 ML_METHOD(MLIntegerT, EnumValueT) {
310 //<Value
311 //>integer
312 	enum_value_t *Value = (enum_value_t *)Args[0];
313 	return ml_integer(Value->Value);
314 }
315 
316 ML_METHOD("|", EnumValueT, MLNilT) {
317 //<Value/1
318 //<Value/2
319 //>EnumValueT
320 	return Args[0];
321 }
322 
323 ML_METHOD("|", MLNilT, EnumValueT) {
324 //<Value/1
325 //<Value/2
326 //>EnumValueT
327 	return Args[1];
328 }
329 
330 ML_METHOD("|", EnumValueT, EnumValueT) {
331 //<Value/1
332 //<Value/2
333 //>EnumValueT
334 	enum_value_t *A = (enum_value_t *)Args[0];
335 	enum_value_t *B = (enum_value_t *)Args[1];
336 	if (A->Type != B->Type) return ml_error("TypeError", "Flags are of different types");
337 	enum_value_t *C = new(enum_value_t);
338 	C->Type = A->Type;
339 	size_t LengthA = ml_string_length(A->Name);
340 	size_t LengthB = ml_string_length(B->Name);
341 	size_t Length = LengthA + LengthB + 1;
342 	char *Name = GC_MALLOC_ATOMIC(Length + 1);
343 	memcpy(Name, ml_string_value(A->Name), LengthA);
344 	Name[LengthA] = '|';
345 	memcpy(Name + LengthA + 1, ml_string_value(B->Name), LengthB);
346 	Name[Length] = 0;
347 	C->Name = ml_string(Name, Length);
348 	C->Value = A->Value | B->Value;
349 	return (ml_value_t *)C;
350 }
351 
array_element_size(GITypeInfo * Info)352 static size_t array_element_size(GITypeInfo *Info) {
353 	switch (g_type_info_get_tag(Info)) {
354 	case GI_TYPE_TAG_VOID: return sizeof(char);
355 	case GI_TYPE_TAG_BOOLEAN: return sizeof(gboolean);
356 	case GI_TYPE_TAG_INT8: return sizeof(gint8);
357 	case GI_TYPE_TAG_UINT8: return sizeof(guint8);
358 	case GI_TYPE_TAG_INT16: return sizeof(gint16);
359 	case GI_TYPE_TAG_UINT16: return sizeof(guint16);
360 	case GI_TYPE_TAG_INT32: return sizeof(gint32);
361 	case GI_TYPE_TAG_UINT32: return sizeof(guint32);
362 	case GI_TYPE_TAG_INT64: return sizeof(gint64);
363 	case GI_TYPE_TAG_UINT64: return sizeof(guint64);
364 	case GI_TYPE_TAG_FLOAT: return sizeof(gfloat);
365 	case GI_TYPE_TAG_DOUBLE: return sizeof(gdouble);
366 	case GI_TYPE_TAG_GTYPE: return sizeof(GType);
367 	case GI_TYPE_TAG_UTF8: return sizeof(char *);
368 	case GI_TYPE_TAG_FILENAME: return sizeof(char *);
369 	case GI_TYPE_TAG_ARRAY: return sizeof(void *);
370 	case GI_TYPE_TAG_INTERFACE: return sizeof(void *);
371 	case GI_TYPE_TAG_GLIST: return sizeof(GList *);
372 	case GI_TYPE_TAG_GSLIST: return sizeof(GSList *);
373 	case GI_TYPE_TAG_GHASH: return sizeof(GHashTable *);
374 	case GI_TYPE_TAG_ERROR: return sizeof(GError *);
375 	case GI_TYPE_TAG_UNICHAR: return sizeof(gunichar);
376 	}
377 	return 0;
378 }
379 
380 typedef struct ml_gir_callback_t {
381 	ml_value_t *Function;
382 	GICallbackInfo *Info;
383 	ffi_cif Cif[1];
384 } ml_gir_callback_t;
385 
386 static ml_value_t *argument_to_ml(GIArgument *Argument, GITypeInfo *TypeInfo, GICallableInfo *Info, GIArgument *ArgsOut);
387 
callback_invoke(ffi_cif * Cif,void * Return,void ** Params,ml_gir_callback_t * Callback)388 static void callback_invoke(ffi_cif *Cif, void *Return, void **Params, ml_gir_callback_t *Callback) {
389 	GICallbackInfo *Info = Callback->Info;
390 	int Count = g_callable_info_get_n_args((GICallableInfo *)Info);
391 	ml_value_t *Args[Count];
392 	for (int I = 0; I < Count; ++I) {
393 		Args[I] = MLNil;
394 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
395 		GITypeInfo TypeInfo[1];
396 		g_arg_info_load_type(ArgInfo, TypeInfo);
397 		switch (g_type_info_get_tag(TypeInfo)) {
398 		case GI_TYPE_TAG_VOID:
399 			Args[I] = MLNil;
400 			break;
401 		case GI_TYPE_TAG_BOOLEAN:
402 			Args[I] = ml_boolean(*(int *)Params[I]);
403 			break;
404 		case GI_TYPE_TAG_INT8:
405 			Args[I] = ml_integer(*(int8_t *)Params[I]);
406 			break;
407 		case GI_TYPE_TAG_UINT8:
408 			Args[I] = ml_integer(*(uint8_t *)Params[I]);
409 			break;
410 		case GI_TYPE_TAG_INT16:
411 			Args[I] = ml_integer(*(int16_t *)Params[I]);
412 			break;
413 		case GI_TYPE_TAG_UINT16:
414 			Args[I] = ml_integer(*(uint16_t *)Params[I]);
415 			break;
416 		case GI_TYPE_TAG_INT32:
417 			Args[I] = ml_integer(*(int32_t *)Params[I]);
418 			break;
419 		case GI_TYPE_TAG_UINT32:
420 			Args[I] = ml_integer(*(uint32_t *)Params[I]);
421 			break;
422 		case GI_TYPE_TAG_INT64:
423 			Args[I] = ml_integer(*(int64_t *)Params[I]);
424 			break;
425 		case GI_TYPE_TAG_UINT64:
426 			Args[I] = ml_integer(*(uint64_t *)Params[I]);
427 			break;
428 		case GI_TYPE_TAG_FLOAT:
429 		case GI_TYPE_TAG_DOUBLE:
430 			Args[I] = ml_real(*(double *)Params[I]);
431 			break;
432 		case GI_TYPE_TAG_GTYPE:
433 			break;
434 		case GI_TYPE_TAG_UTF8:
435 		case GI_TYPE_TAG_FILENAME:
436 			Args[I] = ml_string(*(char **)Params[I], -1);
437 			break;
438 		case GI_TYPE_TAG_ARRAY:
439 		case GI_TYPE_TAG_INTERFACE:
440 		case GI_TYPE_TAG_GLIST:
441 		case GI_TYPE_TAG_GSLIST:
442 		case GI_TYPE_TAG_GHASH: {
443 			GIArgument Argument = {.v_pointer = *(void **)Params[I]};
444 			Args[I] = argument_to_ml(&Argument, TypeInfo, NULL, NULL);
445 			break;
446 		}
447 		case GI_TYPE_TAG_ERROR: {
448 			GError *Error = *(GError **)Params[I];
449 			Args[I] = ml_error("GError", "%s", Error->message);
450 			break;
451 		}
452 		case GI_TYPE_TAG_UNICHAR:
453 			Args[I] = ml_integer(*(gunichar *)Params[I]);
454 			break;
455 		}
456 	}
457 	ml_value_t *Result = ml_simple_call(Callback->Function, Count, Args);
458 	GITypeInfo *ReturnInfo = g_callable_info_get_return_type((GICallableInfo *)Info);
459 	switch (g_type_info_get_tag(ReturnInfo)) {
460 	case GI_TYPE_TAG_VOID: break;
461 	case GI_TYPE_TAG_BOOLEAN:
462 		*(int *)Return = ml_boolean_value(Result);
463 		break;
464 	case GI_TYPE_TAG_INT8:
465 		*(int8_t *)Return = ml_integer_value(Result);
466 		break;
467 	case GI_TYPE_TAG_UINT8:
468 		*(uint8_t *)Return = ml_integer_value(Result);
469 		break;
470 	case GI_TYPE_TAG_INT16:
471 		*(int16_t *)Return = ml_integer_value(Result);
472 		break;
473 	case GI_TYPE_TAG_UINT16:
474 		*(uint16_t *)Return = ml_integer_value(Result);
475 		break;
476 	case GI_TYPE_TAG_INT32:
477 		*(int32_t *)Return = ml_integer_value(Result);
478 		break;
479 	case GI_TYPE_TAG_UINT32:
480 		*(uint32_t *)Return = ml_integer_value(Result);
481 		break;
482 	case GI_TYPE_TAG_INT64:
483 		*(int64_t *)Return = ml_integer_value(Result);
484 		break;
485 	case GI_TYPE_TAG_UINT64:
486 		*(uint64_t *)Return = ml_integer_value(Result);
487 		break;
488 	case GI_TYPE_TAG_FLOAT:
489 	case GI_TYPE_TAG_DOUBLE:
490 		*(double *)Return = ml_real_value(Result);
491 		break;
492 	case GI_TYPE_TAG_GTYPE: {
493 		break;
494 	}
495 	case GI_TYPE_TAG_UTF8:
496 	case GI_TYPE_TAG_FILENAME:
497 		*(const char **)Return = ml_string_value(Result);
498 		break;
499 	case GI_TYPE_TAG_ARRAY: {
500 		if (!ml_is(Result, MLListT)) {
501 			*(void **)Return = 0;
502 			break;
503 		}
504 		GITypeInfo *ElementInfo = g_type_info_get_param_type(ReturnInfo, 0);
505 		size_t ElementSize = array_element_size(ElementInfo);
506 		char *Array = GC_MALLOC_ATOMIC((ml_list_length(Result) + 1) * ElementSize);
507 		// TODO: fill array
508 		*(void **)Result = Array;
509 		break;
510 	}
511 	case GI_TYPE_TAG_INTERFACE: {
512 		GIBaseInfo *InterfaceInfo = g_type_info_get_interface(ReturnInfo);
513 		switch (g_base_info_get_type(InterfaceInfo)) {
514 		case GI_INFO_TYPE_INVALID:
515 		case GI_INFO_TYPE_INVALID_0: break;
516 		case GI_INFO_TYPE_FUNCTION: break;
517 		case GI_INFO_TYPE_CALLBACK: {
518 			ml_gir_callback_t *Callback = (ml_gir_callback_t *)GC_MALLOC_UNCOLLECTABLE(sizeof(ml_gir_callback_t));
519 			Callback->Info = InterfaceInfo;
520 			Callback->Function = Result;
521 			*(void **)Return = g_callable_info_prepare_closure(
522 				InterfaceInfo,
523 				Callback->Cif,
524 				(GIFFIClosureCallback)callback_invoke,
525 				Callback
526 			);
527 			break;
528 		}
529 		case GI_INFO_TYPE_STRUCT: {
530 			if (ml_is(Result, StructInstanceT)) {
531 				*(void **)Return = ((struct_instance_t *)Result)->Value;
532 			} else {
533 				*(void **)Return = 0;
534 			}
535 			break;
536 		}
537 		case GI_INFO_TYPE_BOXED: break;
538 		case GI_INFO_TYPE_ENUM: {
539 			if (ml_is(Result, EnumValueT)) {
540 				*(int *)Return = ((enum_value_t *)Result)->Value;
541 			} else {
542 				*(int *)Return = 0;
543 			}
544 			break;
545 		}
546 		case GI_INFO_TYPE_FLAGS: break;
547 		case GI_INFO_TYPE_OBJECT: {
548 			if (ml_is(Result, ObjectInstanceT)) {
549 				*(void **)Return = ((object_instance_t *)Result)->Handle;
550 			} else {
551 				*(void **)Return = 0;
552 			}
553 			break;
554 		}
555 		case GI_INFO_TYPE_INTERFACE: {
556 			if (ml_is(Result, ObjectInstanceT)) {
557 				*(void **)Return = ((object_instance_t *)Result)->Handle;
558 			} else {
559 				*(void **)Return = 0;
560 			}
561 			break;
562 		}
563 		case GI_INFO_TYPE_CONSTANT: break;
564 		case GI_INFO_TYPE_UNION: break;
565 		case GI_INFO_TYPE_VALUE: break;
566 		case GI_INFO_TYPE_SIGNAL: break;
567 		case GI_INFO_TYPE_VFUNC: break;
568 		case GI_INFO_TYPE_PROPERTY: break;
569 		case GI_INFO_TYPE_FIELD: break;
570 		case GI_INFO_TYPE_ARG: break;
571 		case GI_INFO_TYPE_TYPE: break;
572 		case GI_INFO_TYPE_UNRESOLVED: break;
573 		}
574 		break;
575 	}
576 	case GI_TYPE_TAG_GLIST: {
577 		break;
578 	}
579 	case GI_TYPE_TAG_GSLIST: {
580 		break;
581 	}
582 	case GI_TYPE_TAG_GHASH: {
583 		break;
584 	}
585 	case GI_TYPE_TAG_ERROR: {
586 		break;
587 	}
588 	case GI_TYPE_TAG_UNICHAR: {
589 		break;
590 	}
591 	}
592 }
593 
594 static GIBaseInfo *GValueInfo;
595 
get_output_length(GICallableInfo * Info,int Index,GIArgument * ArgsOut)596 static size_t get_output_length(GICallableInfo *Info, int Index, GIArgument *ArgsOut) {
597 	for (int I = 0; I < Index; ++I) {
598 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
599 		if (g_arg_info_get_direction(ArgInfo) != GI_DIRECTION_IN) {
600 			++ArgsOut;
601 		}
602 	}
603 	return ((GIArgument *)ArgsOut->v_pointer)->v_uint64;
604 }
605 
606 typedef struct {
607 	ml_value_t *Result;
608 	GITypeInfo *KeyInfo;
609 	GITypeInfo *ValueInfo;
610 } hashtable_to_map_t;
611 
hashtable_to_map(gpointer KeyPtr,gpointer ValuePtr,hashtable_to_map_t * Info)612 static void hashtable_to_map(gpointer KeyPtr, gpointer ValuePtr, hashtable_to_map_t *Info) {
613 	GIArgument Argument = {.v_pointer = KeyPtr};
614 	ml_value_t *Key = argument_to_ml(&Argument, Info->KeyInfo, NULL, NULL);
615 	Argument.v_pointer = ValuePtr;
616 	ml_value_t *Value = argument_to_ml(&Argument, Info->ValueInfo, NULL, NULL);
617 	ml_map_insert(Info->Result, Key, Value);
618 }
619 
argument_to_ml(GIArgument * Argument,GITypeInfo * TypeInfo,GICallableInfo * Info,GIArgument * ArgsOut)620 static ml_value_t *argument_to_ml(GIArgument *Argument, GITypeInfo *TypeInfo, GICallableInfo *Info, GIArgument *ArgsOut) {
621 	switch (g_type_info_get_tag(TypeInfo)) {
622 	case GI_TYPE_TAG_VOID: {
623 		return MLNil;
624 	}
625 	case GI_TYPE_TAG_BOOLEAN: {
626 		return ml_boolean(Argument->v_boolean);
627 	}
628 	case GI_TYPE_TAG_INT8: {
629 		return ml_integer(Argument->v_int8);
630 	}
631 	case GI_TYPE_TAG_UINT8: {
632 		return ml_integer(Argument->v_uint8);
633 	}
634 	case GI_TYPE_TAG_INT16: {
635 		return ml_integer(Argument->v_int16);
636 	}
637 	case GI_TYPE_TAG_UINT16: {
638 		return ml_integer(Argument->v_uint16);
639 	}
640 	case GI_TYPE_TAG_INT32: {
641 		return ml_integer(Argument->v_int32);
642 	}
643 	case GI_TYPE_TAG_UINT32: {
644 		return ml_integer(Argument->v_uint32);
645 	}
646 	case GI_TYPE_TAG_INT64: {
647 		return ml_integer(Argument->v_int64);
648 	}
649 	case GI_TYPE_TAG_UINT64: {
650 		return ml_integer(Argument->v_uint64);
651 	}
652 	case GI_TYPE_TAG_FLOAT: {
653 		return ml_real(Argument->v_float);
654 	}
655 	case GI_TYPE_TAG_DOUBLE: {
656 		return ml_real(Argument->v_double);
657 	}
658 	case GI_TYPE_TAG_GTYPE: {
659 		return ml_cstring(g_type_name(Argument->v_size));
660 	}
661 	case GI_TYPE_TAG_UTF8:
662 	case GI_TYPE_TAG_FILENAME: {
663 		return ml_string(Argument->v_string, -1);
664 	}
665 	case GI_TYPE_TAG_ARRAY: {
666 		GITypeInfo *ElementInfo = g_type_info_get_param_type(TypeInfo, 0);
667 		switch (g_type_info_get_tag(ElementInfo)) {
668 		case GI_TYPE_TAG_INT8:
669 		case GI_TYPE_TAG_UINT8: {
670 			if (g_type_info_is_zero_terminated(TypeInfo)) {
671 				return ml_cstring(Argument->v_string);
672 			} else {
673 				size_t Length;
674 				int LengthIndex = g_type_info_get_array_length(TypeInfo);
675 				if (LengthIndex < 0) {
676 					Length = g_type_info_get_array_fixed_size(TypeInfo);
677 				} else {
678 					if (!Info) return ml_error("ValueError", "Unsupported situtation");
679 					Length = get_output_length(Info, LengthIndex, ArgsOut);
680 				}
681 				return ml_string(Argument->v_string, Length);
682 			}
683 			break;
684 		}
685 		default: break;
686 		}
687 		break;
688 	}
689 	case GI_TYPE_TAG_INTERFACE: {
690 		GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
691 		//printf("Interface = %s\n", g_base_info_get_name(InterfaceInfo));
692 		if (g_base_info_equal(InterfaceInfo, GValueInfo)) {
693 			return _value_to_ml(Argument->v_pointer, NULL);
694 		} else switch (g_base_info_get_type(InterfaceInfo)) {
695 		case GI_INFO_TYPE_INVALID:
696 		case GI_INFO_TYPE_INVALID_0: break;
697 		case GI_INFO_TYPE_FUNCTION: break;
698 		case GI_INFO_TYPE_CALLBACK: break;
699 		case GI_INFO_TYPE_STRUCT: {
700 			struct_instance_t *Instance = new(struct_instance_t);
701 			Instance->Type = (struct_t *)struct_info_lookup((GIStructInfo *)InterfaceInfo);
702 			Instance->Value = Argument->v_pointer;
703 			return (ml_value_t *)Instance;
704 		}
705 		case GI_INFO_TYPE_BOXED: {
706 			break;
707 		}
708 		case GI_INFO_TYPE_ENUM: {
709 			enum_t *Enum = (enum_t *)enum_info_lookup((GIEnumInfo *)InterfaceInfo);
710 			return Enum->ByIndex[Argument->v_int];
711 		}
712 		case GI_INFO_TYPE_FLAGS: {
713 			break;
714 		}
715 		case GI_INFO_TYPE_OBJECT:
716 		case GI_INFO_TYPE_INTERFACE: {
717 			return ml_gir_instance_get(Argument->v_pointer, InterfaceInfo);
718 			break;
719 		}
720 		case GI_INFO_TYPE_CONSTANT: {
721 			break;
722 		}
723 		case GI_INFO_TYPE_UNION: {
724 			break;
725 		}
726 		case GI_INFO_TYPE_VALUE: {
727 			break;
728 		}
729 		case GI_INFO_TYPE_SIGNAL: {
730 			break;
731 		}
732 		case GI_INFO_TYPE_VFUNC: {
733 			break;
734 		}
735 		case GI_INFO_TYPE_PROPERTY: {
736 			break;
737 		}
738 		case GI_INFO_TYPE_FIELD: {
739 			break;
740 		}
741 		case GI_INFO_TYPE_ARG: {
742 			break;
743 		}
744 		case GI_INFO_TYPE_TYPE: {
745 			break;
746 		}
747 		case GI_INFO_TYPE_UNRESOLVED: {
748 			break;
749 		}
750 		}
751 		break;
752 	}
753 	case GI_TYPE_TAG_GLIST: {
754 		if (!Argument->v_pointer) return MLNil;
755 		ml_value_t *Result = ml_list();
756 		GITypeInfo *ElementInfo = g_type_info_get_param_type(TypeInfo, 0);
757 		for (GList *List = (GList *)Argument->v_pointer; List; List = List->next) {
758 			GIArgument Element = {.v_pointer = List->data};
759 			ml_list_put(Result, argument_to_ml(&Element, ElementInfo, NULL, NULL));
760 		}
761 		return Result;
762 	}
763 	case GI_TYPE_TAG_GSLIST: {
764 		if (!Argument->v_pointer) return MLNil;
765 		ml_value_t *Result = ml_list();
766 		GITypeInfo *ElementInfo = g_type_info_get_param_type(TypeInfo, 0);
767 		for (GSList *List = (GSList *)Argument->v_pointer; List; List = List->next) {
768 			GIArgument Element = {.v_pointer = List->data};
769 			ml_list_put(Result, argument_to_ml(&Element, ElementInfo, NULL, NULL));
770 		}
771 		return Result;
772 	}
773 	case GI_TYPE_TAG_GHASH: {
774 		if (!Argument->v_pointer) return MLNil;
775 		hashtable_to_map_t Info = {
776 			ml_map(),
777 			g_type_info_get_param_type(TypeInfo, 0),
778 			g_type_info_get_param_type(TypeInfo, 1)
779 		};
780 		g_hash_table_foreach((GHashTable *)Argument->v_pointer, (GHFunc)hashtable_to_map, &Info);
781 		return Info.Result;
782 	}
783 	case GI_TYPE_TAG_ERROR: {
784 		GError *Error = Argument->v_pointer;
785 		return ml_error("GError", "%s", Error->message);
786 	}
787 	case GI_TYPE_TAG_UNICHAR: {
788 		return ml_integer(Argument->v_uint32);
789 	}
790 	}
791 	return ml_error("ValueError", "Unsupported situtation: %s", g_base_info_get_name((GIBaseInfo *)TypeInfo));
792 }
793 
list_to_array(ml_value_t * List,GITypeInfo * TypeInfo)794 static void *list_to_array(ml_value_t *List, GITypeInfo *TypeInfo) {
795 	size_t ElementSize = array_element_size(TypeInfo);
796 	size_t Length = ml_list_length(List);
797 	char *Array = GC_MALLOC_ATOMIC((Length + 1) * ElementSize);
798 	memset(Array, 0, (Length + 1) * ElementSize);
799 	switch (g_type_info_get_tag(TypeInfo)) {
800 	case GI_TYPE_TAG_BOOLEAN: {
801 		gboolean *Ptr = (gboolean *)Array;
802 		ML_LIST_FOREACH(List, Iter) {
803 			if (ml_is(Iter->Value, MLBooleanT)) {
804 				*Ptr++ = ml_boolean_value(Iter->Value);
805 			}
806 		}
807 		break;
808 	}
809 	case GI_TYPE_TAG_INT8: {
810 		gint8 *Ptr = (gint8 *)Array;
811 		ML_LIST_FOREACH(List, Iter) {
812 			if (ml_is(Iter->Value, MLIntegerT)) {
813 				*Ptr++ = ml_integer_value(Iter->Value);
814 			}
815 		}
816 		break;
817 	}
818 	case GI_TYPE_TAG_UINT8: {
819 		guint8 *Ptr = (guint8 *)Array;
820 		ML_LIST_FOREACH(List, Iter) {
821 			if (ml_is(Iter->Value, MLIntegerT)) {
822 				*Ptr++ = ml_integer_value(Iter->Value);
823 			}
824 		}
825 		break;
826 	}
827 	case GI_TYPE_TAG_INT16: {
828 		gint16 *Ptr = (gint16 *)Array;
829 		ML_LIST_FOREACH(List, Iter) {
830 			if (ml_is(Iter->Value, MLIntegerT)) {
831 				*Ptr++ = ml_integer_value(Iter->Value);
832 			}
833 		}
834 		break;
835 	}
836 	case GI_TYPE_TAG_UINT16: {
837 		guint16 *Ptr = (guint16 *)Array;
838 		ML_LIST_FOREACH(List, Iter) {
839 			if (ml_is(Iter->Value, MLIntegerT)) {
840 				*Ptr++ = ml_integer_value(Iter->Value);
841 			}
842 		}
843 		break;
844 	}
845 	case GI_TYPE_TAG_INT32: {
846 		gint32 *Ptr = (gint32 *)Array;
847 		ML_LIST_FOREACH(List, Iter) {
848 			if (ml_is(Iter->Value, MLIntegerT)) {
849 				*Ptr++ = ml_integer_value(Iter->Value);
850 			}
851 		}
852 		break;
853 	}
854 	case GI_TYPE_TAG_UINT32: {
855 		guint32 *Ptr = (guint32 *)Array;
856 		ML_LIST_FOREACH(List, Iter) {
857 			if (ml_is(Iter->Value, MLIntegerT)) {
858 				*Ptr++ = ml_integer_value(Iter->Value);
859 			}
860 		}
861 		break;
862 	}
863 	case GI_TYPE_TAG_INT64: {
864 		gint64 *Ptr = (gint64 *)Array;
865 		ML_LIST_FOREACH(List, Iter) {
866 			if (ml_is(Iter->Value, MLIntegerT)) {
867 				*Ptr++ = ml_integer_value(Iter->Value);
868 			}
869 		}
870 		break;
871 	}
872 	case GI_TYPE_TAG_UINT64: {
873 		guint64 *Ptr = (guint64 *)Array;
874 		ML_LIST_FOREACH(List, Iter) {
875 			if (ml_is(Iter->Value, MLIntegerT)) {
876 				*Ptr++ = ml_integer_value(Iter->Value);
877 			}
878 		}
879 		break;
880 	}
881 	case GI_TYPE_TAG_FLOAT: {
882 		gfloat *Ptr = (gfloat *)Array;
883 		ML_LIST_FOREACH(List, Iter) {
884 			if (ml_is(Iter->Value, MLDoubleT)) {
885 				*Ptr++ = ml_real_value(Iter->Value);
886 			}
887 		}
888 		break;
889 	}
890 	case GI_TYPE_TAG_DOUBLE: {
891 		gdouble *Ptr = (gdouble *)Array;
892 		ML_LIST_FOREACH(List, Iter) {
893 			if (ml_is(Iter->Value, MLDoubleT)) {
894 				*Ptr++ = ml_real_value(Iter->Value);
895 			}
896 		}
897 		break;
898 	}
899 	case GI_TYPE_TAG_GTYPE: {
900 		break;
901 	}
902 	case GI_TYPE_TAG_UTF8:
903 	case GI_TYPE_TAG_FILENAME: {
904 		const gchar **Ptr = (const gchar **)Array;
905 		ML_LIST_FOREACH(List, Iter) {
906 			if (Iter->Value == MLNil) {
907 				*Ptr++ = NULL;
908 			} else if (ml_is(Iter->Value, MLStringT)) {
909 				*Ptr++ = ml_string_value(Iter->Value);
910 			}
911 		}
912 		break;
913 	}
914 	default:
915 		break;
916 	}
917 	return Array;
918 }
919 
list_to_slist(ml_value_t * List,GITypeInfo * TypeInfo)920 static GSList *list_to_slist(ml_value_t *List, GITypeInfo *TypeInfo) {
921 	GSList *Head = NULL, **Slot = &Head;
922 	switch (g_type_info_get_tag(TypeInfo)) {
923 	case GI_TYPE_TAG_BOOLEAN: {
924 		ML_LIST_FOREACH(List, Iter) {
925 			if (ml_is(Iter->Value, MLBooleanT)) {
926 				GSList *Node = Slot[0] = g_slist_alloc();
927 				Node->data = GINT_TO_POINTER(ml_boolean_value(Iter->Value));
928 				Slot = &Node->next;
929 			}
930 		}
931 		break;
932 	}
933 	case GI_TYPE_TAG_INT8:
934 	case GI_TYPE_TAG_UINT8:
935 	case GI_TYPE_TAG_INT16:
936 	case GI_TYPE_TAG_UINT16:
937 	case GI_TYPE_TAG_INT32:
938 	case GI_TYPE_TAG_UINT32:
939 	case GI_TYPE_TAG_INT64:
940 	case GI_TYPE_TAG_UINT64: {
941 		ML_LIST_FOREACH(List, Iter) {
942 			if (ml_is(Iter->Value, MLIntegerT)) {
943 				GSList *Node = Slot[0] = g_slist_alloc();
944 				Node->data = GINT_TO_POINTER(ml_integer_value(Iter->Value));
945 				Slot = &Node->next;
946 			}
947 		}
948 		break;
949 	}
950 	case GI_TYPE_TAG_GTYPE: {
951 		ML_LIST_FOREACH(List, Iter) {
952 			if (ml_is(Iter->Value, BaseInfoT)) {
953 				baseinfo_t *Base = (baseinfo_t *)Iter->Value;
954 				GSList *Node = Slot[0] = g_slist_alloc();
955 				Node->data = GINT_TO_POINTER(g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)Base->Info));
956 				Slot = &Node->next;
957 			} else if (ml_is(Iter->Value, MLStringT)) {
958 				GSList *Node = Slot[0] = g_slist_alloc();
959 				Node->data = GINT_TO_POINTER(g_type_from_name(ml_string_value(Iter->Value)));
960 				Slot = &Node->next;
961 			}
962 		}
963 		break;
964 	}
965 	case GI_TYPE_TAG_UTF8:
966 	case GI_TYPE_TAG_FILENAME: {
967 		ML_LIST_FOREACH(List, Iter) {
968 			if (Iter->Value == MLNil) {
969 				GSList *Node = Slot[0] = g_slist_alloc();
970 				Node->data = NULL;
971 				Slot = &Node->next;
972 			} else if (ml_is(Iter->Value, MLStringT)) {
973 				GSList *Node = Slot[0] = g_slist_alloc();
974 				Node->data = (void *)ml_string_value(Iter->Value);
975 				Slot = &Node->next;
976 			}
977 		}
978 		break;
979 	}
980 	case GI_TYPE_TAG_INTERFACE: {
981 		GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
982 		if (g_base_info_equal(InterfaceInfo, GValueInfo)) {
983 			GValue *GValues = anew(GValue, ml_list_length(List));
984 			GValue *Value = GValues;
985 			ML_LIST_FOREACH(List, Iter) {
986 				GSList *Node = Slot[0] = g_slist_alloc();
987 				_ml_to_value(Iter->Value, Value);
988 				Node->data = Value++;
989 				Slot = &Node->next;
990 			}
991 		} else switch (g_base_info_get_type(InterfaceInfo)) {
992 		case GI_INFO_TYPE_CALLBACK: {
993 			ML_LIST_FOREACH(List, Iter) {
994 				GSList *Node = Slot[0] = g_slist_alloc();
995 				ml_gir_callback_t *Callback = (ml_gir_callback_t *)GC_MALLOC_UNCOLLECTABLE(sizeof(ml_gir_callback_t));
996 				Callback->Info = InterfaceInfo;
997 				Callback->Function = Iter->Value;
998 				Node->data = g_callable_info_prepare_closure(
999 					InterfaceInfo,
1000 					Callback->Cif,
1001 					(GIFFIClosureCallback)callback_invoke,
1002 					Callback
1003 				);
1004 				Slot = &Node->next;
1005 			}
1006 			break;
1007 		}
1008 		case GI_INFO_TYPE_STRUCT: {
1009 			ML_LIST_FOREACH(List, Iter) {
1010 				GSList *Node = Slot[0] = g_slist_alloc();
1011 				if (Iter->Value == MLNil) {
1012 					Node->data = NULL;
1013 				} else if (ml_is(Iter->Value, StructInstanceT)) {
1014 					Node->data = ((struct_instance_t *)Iter->Value)->Value;
1015 				}
1016 				Slot = &Node->next;
1017 			}
1018 			break;
1019 		}
1020 		case GI_INFO_TYPE_ENUM:
1021 		case GI_INFO_TYPE_FLAGS: {
1022 			ML_LIST_FOREACH(List, Iter) {
1023 				GSList *Node = Slot[0] = g_slist_alloc();
1024 				if (Iter->Value == MLNil) {
1025 					Node->data = GINT_TO_POINTER(0);
1026 				} else if (ml_is(Iter->Value, EnumValueT)) {
1027 					Node->data = GINT_TO_POINTER(((enum_value_t *)Iter->Value)->Value);
1028 				}
1029 				Slot = &Node->next;
1030 			}
1031 			break;
1032 		}
1033 		case GI_INFO_TYPE_OBJECT:
1034 		case GI_INFO_TYPE_INTERFACE: {
1035 			ML_LIST_FOREACH(List, Iter) {
1036 				GSList *Node = Slot[0] = g_slist_alloc();
1037 				if (Iter->Value == MLNil) {
1038 					Node->data = NULL;
1039 				} else if (ml_is(Iter->Value, ObjectInstanceT)) {
1040 					Node->data = ((object_instance_t *)Iter->Value)->Handle;
1041 				}
1042 				Slot = &Node->next;
1043 			}
1044 			break;
1045 		}
1046 		default:
1047 			break;
1048 		}
1049 		break;
1050 	}
1051 	default:
1052 		break;
1053 	}
1054 	return Head;
1055 }
1056 
set_input_length(GICallableInfo * Info,int Index,GIArgument * ArgsIn,gsize Length)1057 static void set_input_length(GICallableInfo *Info, int Index, GIArgument *ArgsIn, gsize Length) {
1058 	if (g_function_info_get_flags(Info) & GI_FUNCTION_IS_METHOD) ++ArgsIn;
1059 	for (int I = 0; I < Index; ++I) {
1060 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
1061 		if (g_arg_info_get_direction(ArgInfo) != GI_DIRECTION_OUT) {
1062 			++ArgsIn;
1063 		}
1064 	}
1065 	ArgsIn->v_uint64 = Length;
1066 }
1067 
1068 static GIBaseInfo *DestroyNotifyInfo;
1069 
function_info_invoke(GIFunctionInfo * Info,int Count,ml_value_t ** Args)1070 static ml_value_t *function_info_invoke(GIFunctionInfo *Info, int Count, ml_value_t **Args) {
1071 	int NArgs = g_callable_info_get_n_args((GICallableInfo *)Info);
1072 	int NArgsIn = 0, NArgsOut = 0;
1073 	for (int I = 0; I < NArgs; ++I) {
1074 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
1075 		switch (g_arg_info_get_direction(ArgInfo)) {
1076 		case GI_DIRECTION_IN: ++NArgsIn; break;
1077 		case GI_DIRECTION_OUT: ++NArgsOut; break;
1078 		case GI_DIRECTION_INOUT: ++NArgsIn; ++NArgsOut; break;
1079 		}
1080 	}
1081 	//GIFunctionInfoFlags Flags = g_function_info_get_flags(Info);
1082 	GIArgument ArgsIn[NArgsIn];
1083 	GIArgument ArgsOut[NArgsOut];
1084 	GIArgument ResultsOut[NArgsOut];
1085 	GValue GValues[NArgs];
1086 	for (int I = 0; I < NArgsIn; ++I) ArgsIn[I].v_pointer = NULL;
1087 	int IndexIn = 0, IndexOut = 0, IndexResult = 0, IndexValue = 0, N = 0;
1088 	if (g_function_info_get_flags(Info) & GI_FUNCTION_IS_METHOD) {
1089 		ArgsIn[0].v_pointer = ((object_instance_t *)Args[0])->Handle;
1090 		N = 1;
1091 		IndexIn = 1;
1092 	}
1093 	//printf("%s(", g_base_info_get_name((GIBaseInfo *)Info));
1094 	uint64_t Skips = 0;
1095 	for (int I = 0; I < NArgs; ++I) {
1096 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
1097 		int ClosureArg = g_arg_info_get_closure(ArgInfo);
1098 		if (ClosureArg >= 0) Skips |= 1 << ClosureArg;
1099 		GITypeInfo TypeInfo[1];
1100 		g_arg_info_load_type(ArgInfo, TypeInfo);
1101 		//printf(I ? ", %s : %d" : "%s : %d", g_base_info_get_name((GIBaseInfo *)ArgInfo), g_type_info_get_tag(TypeInfo));
1102 		if (g_type_info_get_tag(TypeInfo) == GI_TYPE_TAG_ARRAY) {
1103 			int LengthIndex = g_type_info_get_array_length(TypeInfo);
1104 			if (LengthIndex >= 0) {
1105 				Skips |= 1 << LengthIndex;
1106 			}
1107 		}
1108 	}
1109 	//printf(")\n");
1110 	for (int I = 0; I < NArgs; ++I, Skips >>= 1) {
1111 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
1112 		GITypeInfo TypeInfo[1];
1113 		g_arg_info_load_type(ArgInfo, TypeInfo);
1114 		GIDirection Direction = g_arg_info_get_direction(ArgInfo);
1115 		if (Direction == GI_DIRECTION_IN || Direction == GI_DIRECTION_INOUT) {
1116 			if (Skips % 2) goto skip_in_arg;
1117 			GITypeTag Tag = g_type_info_get_tag(TypeInfo);
1118 			if (N >= Count) {
1119 				if (Tag == GI_TYPE_TAG_INTERFACE) {
1120 					GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
1121 					if (g_base_info_equal(InterfaceInfo, DestroyNotifyInfo)) {
1122 						ArgsIn[IndexIn].v_pointer = NULL;
1123 						goto skip_in_arg;
1124 					}
1125 				}
1126 				return ml_error("InvokeError", "Not enough arguments");
1127 			}
1128 			ml_value_t *Arg = Args[N++];
1129 			switch (Tag) {
1130 			case GI_TYPE_TAG_VOID: break;
1131 			case GI_TYPE_TAG_BOOLEAN: {
1132 				ArgsIn[IndexIn].v_boolean = ml_boolean_value(Arg);
1133 				break;
1134 			}
1135 			case GI_TYPE_TAG_INT8: {
1136 				ArgsIn[IndexIn].v_int8 = ml_integer_value(Arg);
1137 				break;
1138 			}
1139 			case GI_TYPE_TAG_UINT8: {
1140 				ArgsIn[IndexIn].v_uint8 = ml_integer_value(Arg);
1141 				break;
1142 			}
1143 			case GI_TYPE_TAG_INT16: {
1144 				ArgsIn[IndexIn].v_int16 = ml_integer_value(Arg);
1145 				break;
1146 			}
1147 			case GI_TYPE_TAG_UINT16: {
1148 				ArgsIn[IndexIn].v_uint16 = ml_integer_value(Arg);
1149 				break;
1150 			}
1151 			case GI_TYPE_TAG_INT32: {
1152 				ArgsIn[IndexIn].v_int32 = ml_integer_value(Arg);
1153 				break;
1154 			}
1155 			case GI_TYPE_TAG_UINT32: {
1156 				ArgsIn[IndexIn].v_uint32 = ml_integer_value(Arg);
1157 				break;
1158 			}
1159 			case GI_TYPE_TAG_INT64: {
1160 				ArgsIn[IndexIn].v_int64 = ml_integer_value(Arg);
1161 				break;
1162 			}
1163 			case GI_TYPE_TAG_UINT64: {
1164 				ArgsIn[IndexIn].v_uint64 = ml_integer_value(Arg);
1165 				break;
1166 			}
1167 			case GI_TYPE_TAG_FLOAT: {
1168 				ArgsIn[IndexIn].v_float = ml_real_value(Arg);
1169 				break;
1170 			}
1171 			case GI_TYPE_TAG_DOUBLE: {
1172 				ArgsIn[IndexIn].v_double = ml_real_value(Arg);
1173 				break;
1174 			}
1175 			case GI_TYPE_TAG_GTYPE: {
1176 				if (ml_is(Arg, BaseInfoT)) {
1177 					baseinfo_t *Base = (baseinfo_t *)Arg;
1178 					ArgsIn[IndexIn].v_size = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)Base->Info);
1179 				} else if (ml_is(Arg, MLStringT)) {
1180 					ArgsIn[IndexIn].v_size = g_type_from_name(ml_string_value(Arg));
1181 				} else if (Arg == (ml_value_t *)MLNilT) {
1182 					ArgsIn[IndexIn].v_size = G_TYPE_NONE;
1183 				} else if (Arg == (ml_value_t *)MLIntegerT) {
1184 					ArgsIn[IndexIn].v_size = G_TYPE_INT64;
1185 				} else if (Arg == (ml_value_t *)MLStringT) {
1186 					ArgsIn[IndexIn].v_size = G_TYPE_STRING;
1187 				} else if (Arg == (ml_value_t *)MLDoubleT) {
1188 					ArgsIn[IndexIn].v_size = G_TYPE_DOUBLE;
1189 				} else if (Arg == (ml_value_t *)MLBooleanT) {
1190 					ArgsIn[IndexIn].v_size = G_TYPE_BOOLEAN;
1191 				} else {
1192 					return ml_error("TypeError", "Expected type for parameter %d", I);
1193 				}
1194 				break;
1195 			}
1196 			case GI_TYPE_TAG_UTF8:
1197 			case GI_TYPE_TAG_FILENAME: {
1198 				if (Arg == MLNil) {
1199 					ArgsIn[IndexIn].v_string = NULL;
1200 				} else {
1201 					ML_CHECK_ARG_TYPE(N - 1, MLStringT);
1202 					ArgsIn[IndexIn].v_string = (char *)ml_string_value(Arg);
1203 				}
1204 				break;
1205 			}
1206 			case GI_TYPE_TAG_ARRAY: {
1207 				GITypeInfo *ElementInfo = g_type_info_get_param_type(TypeInfo, 0);
1208 				int LengthIndex = g_type_info_get_array_length(TypeInfo);
1209 				switch (g_type_info_get_tag(ElementInfo)) {
1210 				case GI_TYPE_TAG_INT8:
1211 				case GI_TYPE_TAG_UINT8: {
1212 					if (ml_is(Arg, MLStringT)) {
1213 						ArgsIn[IndexIn].v_pointer = (void *)ml_string_value(Arg);
1214 						if (LengthIndex >= 0) {
1215 							set_input_length(Info, LengthIndex, ArgsIn, ml_string_length(Arg));
1216 						}
1217 					} else if (ml_is(Arg, MLListT)) {
1218 						ArgsIn[IndexIn].v_pointer = list_to_array(Arg, ElementInfo);
1219 						if (LengthIndex >= 0) {
1220 							set_input_length(Info, LengthIndex, ArgsIn, ml_list_length(Arg));
1221 						}
1222 					} else {
1223 						return ml_error("TypeError", "Expected list for parameter %d", I);
1224 					}
1225 					break;
1226 				}
1227 				default: {
1228 					if (!ml_is(Arg, MLListT)) {
1229 						return ml_error("TypeError", "Expected list for parameter %d", I);
1230 					}
1231 					ArgsIn[IndexIn].v_pointer = list_to_array(Arg, ElementInfo);
1232 					if (LengthIndex >= 0) {
1233 						set_input_length(Info, LengthIndex, ArgsIn, ml_list_length(Arg));
1234 					}
1235 					break;
1236 				}
1237 				}
1238 				break;
1239 			}
1240 			case GI_TYPE_TAG_INTERFACE: {
1241 				GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
1242 				if (g_base_info_equal(InterfaceInfo, GValueInfo)) {
1243 					ArgsIn[IndexIn].v_pointer = &GValues[IndexValue];
1244 					memset(&GValues[IndexValue], 0, sizeof(GValue));
1245 					_ml_to_value(Arg, &GValues[IndexValue]);
1246 					++IndexValue;
1247 				} else switch (g_base_info_get_type(InterfaceInfo)) {
1248 				case GI_INFO_TYPE_INVALID:
1249 				case GI_INFO_TYPE_INVALID_0: {
1250 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1251 				}
1252 				case GI_INFO_TYPE_FUNCTION: {
1253 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1254 				}
1255 				case GI_INFO_TYPE_CALLBACK: {
1256 					ml_gir_callback_t *Callback = (ml_gir_callback_t *)GC_MALLOC_UNCOLLECTABLE(sizeof(ml_gir_callback_t));
1257 					Callback->Info = InterfaceInfo;
1258 					Callback->Function = Arg;
1259 					ArgsIn[IndexIn].v_pointer = g_callable_info_prepare_closure(
1260 						InterfaceInfo,
1261 						Callback->Cif,
1262 						(GIFFIClosureCallback)callback_invoke,
1263 						Callback
1264 					);
1265 					break;
1266 				}
1267 				case GI_INFO_TYPE_STRUCT: {
1268 					if (Arg == MLNil) {
1269 						ArgsIn[IndexIn].v_pointer = NULL;
1270 					} else if (ml_is(Arg, StructInstanceT)) {
1271 						ArgsIn[IndexIn].v_pointer = ((struct_instance_t *)Arg)->Value;
1272 					} else {
1273 						return ml_error("TypeError", "Expected gir struct not %s for parameter %d", ml_typeof(Args[I])->Name, I);
1274 					}
1275 					break;
1276 				}
1277 				case GI_INFO_TYPE_BOXED: {
1278 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1279 				}
1280 				case GI_INFO_TYPE_ENUM:
1281 				case GI_INFO_TYPE_FLAGS: {
1282 					if (Arg == MLNil) {
1283 						ArgsIn[IndexIn].v_int64 = 0;
1284 					} else if (ml_is(Arg, EnumValueT)) {
1285 						ArgsIn[IndexIn].v_int64 = ((enum_value_t *)Arg)->Value;
1286 					} else {
1287 						return ml_error("TypeError", "Expected gir enum not %s for parameter %d", ml_typeof(Args[I])->Name, I);
1288 					}
1289 					break;
1290 				}
1291 				case GI_INFO_TYPE_OBJECT:
1292 				case GI_INFO_TYPE_INTERFACE: {
1293 					if (Arg == MLNil) {
1294 						ArgsIn[IndexIn].v_pointer = NULL;
1295 					} else if (ml_is(Arg, ObjectInstanceT)) {
1296 						ArgsIn[IndexIn].v_pointer = ((object_instance_t *)Arg)->Handle;
1297 					} else {
1298 						return ml_error("TypeError", "Expected gir object not %s for parameter %d", ml_typeof(Args[I])->Name, I);
1299 					}
1300 					break;
1301 				}
1302 				case GI_INFO_TYPE_CONSTANT: {
1303 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1304 				}
1305 				case GI_INFO_TYPE_UNION: {
1306 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1307 				}
1308 				case GI_INFO_TYPE_VALUE: {
1309 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1310 				}
1311 				case GI_INFO_TYPE_SIGNAL: {
1312 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1313 				}
1314 				case GI_INFO_TYPE_VFUNC: {
1315 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1316 				}
1317 				case GI_INFO_TYPE_PROPERTY: {
1318 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1319 				}
1320 				case GI_INFO_TYPE_FIELD: {
1321 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1322 				}
1323 				case GI_INFO_TYPE_ARG: {
1324 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1325 				}
1326 				case GI_INFO_TYPE_TYPE: {
1327 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1328 				}
1329 				case GI_INFO_TYPE_UNRESOLVED: {
1330 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1331 				}
1332 				}
1333 				break;
1334 			}
1335 			case GI_TYPE_TAG_GLIST: {
1336 				break;
1337 			}
1338 			case GI_TYPE_TAG_GSLIST: {
1339 				GITypeInfo *ElementInfo = g_type_info_get_param_type(TypeInfo, 0);
1340 				ArgsIn[IndexIn].v_pointer = list_to_slist(Arg, ElementInfo);
1341 				break;
1342 			}
1343 			case GI_TYPE_TAG_GHASH: {
1344 				break;
1345 			}
1346 			case GI_TYPE_TAG_ERROR: {
1347 				break;
1348 			}
1349 			case GI_TYPE_TAG_UNICHAR: {
1350 				break;
1351 			}
1352 			}
1353 		skip_in_arg:
1354 			++IndexIn;
1355 		}
1356 		if (Direction == GI_DIRECTION_OUT || Direction == GI_DIRECTION_INOUT) {
1357 			switch (g_type_info_get_tag(TypeInfo)) {
1358 			case GI_TYPE_TAG_VOID: break;
1359 			case GI_TYPE_TAG_BOOLEAN:
1360 			case GI_TYPE_TAG_INT8:
1361 			case GI_TYPE_TAG_UINT8:
1362 			case GI_TYPE_TAG_INT16:
1363 			case GI_TYPE_TAG_UINT16:
1364 			case GI_TYPE_TAG_INT32:
1365 			case GI_TYPE_TAG_UINT32:
1366 			case GI_TYPE_TAG_INT64:
1367 			case GI_TYPE_TAG_UINT64:
1368 			case GI_TYPE_TAG_FLOAT:
1369 			case GI_TYPE_TAG_DOUBLE:
1370 			case GI_TYPE_TAG_GTYPE:
1371 			case GI_TYPE_TAG_UTF8:
1372 			case GI_TYPE_TAG_FILENAME:
1373 			case GI_TYPE_TAG_ARRAY: {
1374 				ArgsOut[IndexOut].v_pointer = &ResultsOut[IndexResult++];
1375 				break;
1376 			}
1377 			case GI_TYPE_TAG_INTERFACE: {
1378 				GIBaseInfo *InterfaceInfo = g_type_info_get_interface(TypeInfo);
1379 				if (g_base_info_equal(InterfaceInfo, GValueInfo)) {
1380 					ArgsOut[IndexOut].v_pointer = &GValues[IndexValue];
1381 					ResultsOut[IndexResult++].v_pointer = &GValues[IndexValue];
1382 					memset(&GValues[IndexValue], 0, sizeof(GValue));
1383 					++IndexValue;
1384 				} else switch (g_base_info_get_type(InterfaceInfo)) {
1385 				case GI_INFO_TYPE_INVALID:
1386 				case GI_INFO_TYPE_INVALID_0: {
1387 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1388 				}
1389 				case GI_INFO_TYPE_FUNCTION: {
1390 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1391 				}
1392 				case GI_INFO_TYPE_CALLBACK: {
1393 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1394 				}
1395 				case GI_INFO_TYPE_STRUCT: {
1396 					if (g_arg_info_is_caller_allocates(ArgInfo)) {
1397 						if (N >= Count) return ml_error("InvokeError", "Not enough arguments");
1398 						ml_value_t *Arg = Args[N++];
1399 						if (ml_is(Arg, StructInstanceT)) {
1400 							ArgsOut[IndexOut].v_pointer = ((struct_instance_t *)Arg)->Value;
1401 						} else {
1402 							return ml_error("TypeError", "Expected gir struct not %s for parameter %d", ml_typeof(Args[I])->Name, I);
1403 						}
1404 					} else {
1405 						ArgsOut[IndexOut].v_pointer = &ResultsOut[IndexResult++];
1406 					}
1407 					break;
1408 				}
1409 				case GI_INFO_TYPE_BOXED: {
1410 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1411 				}
1412 				case GI_INFO_TYPE_ENUM: {
1413 					break;
1414 				}
1415 				case GI_INFO_TYPE_FLAGS: {
1416 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1417 				}
1418 				case GI_INFO_TYPE_OBJECT:
1419 				case GI_INFO_TYPE_INTERFACE: {
1420 					ArgsOut[IndexOut].v_pointer = &ResultsOut[IndexResult++];
1421 					break;
1422 				}
1423 				case GI_INFO_TYPE_CONSTANT: {
1424 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1425 				}
1426 				case GI_INFO_TYPE_UNION: {
1427 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1428 				}
1429 				case GI_INFO_TYPE_VALUE: {
1430 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1431 				}
1432 				case GI_INFO_TYPE_SIGNAL: {
1433 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1434 				}
1435 				case GI_INFO_TYPE_VFUNC: {
1436 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1437 				}
1438 				case GI_INFO_TYPE_PROPERTY: {
1439 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1440 				}
1441 				case GI_INFO_TYPE_FIELD: {
1442 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1443 				}
1444 				case GI_INFO_TYPE_ARG: {
1445 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1446 				}
1447 				case GI_INFO_TYPE_TYPE: {
1448 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1449 				}
1450 				case GI_INFO_TYPE_UNRESOLVED: {
1451 					return ml_error("NotImplemented", "Not able to marshal %s yet at %d", g_base_info_get_name(InterfaceInfo), __LINE__);
1452 				}
1453 				}
1454 				break;
1455 			}
1456 			case GI_TYPE_TAG_GLIST: {
1457 				break;
1458 			}
1459 			case GI_TYPE_TAG_GSLIST: {
1460 				break;
1461 			}
1462 			case GI_TYPE_TAG_GHASH: {
1463 				break;
1464 			}
1465 			case GI_TYPE_TAG_ERROR: {
1466 				break;
1467 			}
1468 			case GI_TYPE_TAG_UNICHAR: {
1469 				break;
1470 			}
1471 			}
1472 			++IndexOut;
1473 		}
1474 	}
1475 	GError *Error = 0;
1476 	GIArgument ReturnValue[1];
1477 	gboolean Invoked = g_function_info_invoke(Info, ArgsIn, IndexIn, ArgsOut, IndexOut, ReturnValue, &Error);
1478 	if (!Invoked || Error) return ml_error("InvokeError", "Error: %s", Error->message);
1479 	GITypeInfo *ReturnInfo = g_callable_info_get_return_type((GICallableInfo *)Info);
1480 	if (!IndexResult) return argument_to_ml(ReturnValue, ReturnInfo, (GICallableInfo *)Info, ArgsOut);
1481 	ml_value_t *Result = ml_tuple(IndexResult + 1);
1482 	ml_tuple_set(Result, 1, argument_to_ml(ReturnValue, ReturnInfo, (GICallableInfo *)Info, ArgsOut));
1483 	IndexResult = 0;
1484 	for (int I = 0; I < NArgs; ++I) {
1485 		GIArgInfo *ArgInfo = g_callable_info_get_arg((GICallableInfo *)Info, I);
1486 		GITypeInfo TypeInfo[1];
1487 		g_arg_info_load_type(ArgInfo, TypeInfo);
1488 		GIDirection Direction = g_arg_info_get_direction(ArgInfo);
1489 		if (Direction == GI_DIRECTION_OUT || Direction == GI_DIRECTION_INOUT) {
1490 			if (!g_arg_info_is_caller_allocates(ArgInfo)) {
1491 				ml_tuple_set(Result, IndexResult + 2, argument_to_ml(ResultsOut + IndexResult, TypeInfo, (GICallableInfo *)Info, ArgsOut));
1492 				++IndexResult;
1493 			}
1494 		}
1495 	}
1496 	return Result;
1497 }
1498 
constructor_invoke(GIFunctionInfo * Info,int Count,ml_value_t ** Args)1499 static ml_value_t *constructor_invoke(GIFunctionInfo *Info, int Count, ml_value_t **Args) {
1500 	return function_info_invoke(Info, Count, Args);
1501 }
1502 
method_invoke(GIFunctionInfo * Info,int Count,ml_value_t ** Args)1503 static ml_value_t *method_invoke(GIFunctionInfo *Info, int Count, ml_value_t **Args) {
1504 	return function_info_invoke(Info, Count, Args);
1505 }
1506 
interface_add_methods(object_t * Object,GIInterfaceInfo * Info)1507 static void interface_add_methods(object_t *Object, GIInterfaceInfo *Info) {
1508 	int NumMethods = g_interface_info_get_n_methods(Info);
1509 	for (int I = 0; I < NumMethods; ++I) {
1510 		GIFunctionInfo *MethodInfo = g_interface_info_get_method(Info, I);
1511 		const char *MethodName = g_base_info_get_name((GIBaseInfo *)MethodInfo);
1512 		GIFunctionInfoFlags Flags = g_function_info_get_flags(MethodInfo);
1513 		if (Flags & GI_FUNCTION_IS_METHOD) {
1514 			ml_method_by_name(MethodName, MethodInfo, (ml_callback_t)method_invoke, Object, NULL);
1515 		}
1516 	}
1517 	int NumSignals = g_interface_info_get_n_signals(Info);
1518 	for (int I = 0; I < NumSignals; ++I) {
1519 		GISignalInfo *SignalInfo = g_interface_info_get_signal(Info, I);
1520 		const char *SignalName = g_base_info_get_name((GIBaseInfo *)SignalInfo);
1521 		stringmap_insert(Object->Signals, SignalName, SignalInfo);
1522 	}
1523 }
1524 
object_add_signals(object_t * Object,GIObjectInfo * Info)1525 static void object_add_signals(object_t *Object, GIObjectInfo *Info) {
1526 	int NumSignals = g_object_info_get_n_signals(Info);
1527 	for (int I = 0; I < NumSignals; ++I) {
1528 		GISignalInfo *SignalInfo = g_object_info_get_signal(Info, I);
1529 		const char *SignalName = g_base_info_get_name((GIBaseInfo *)SignalInfo);
1530 		stringmap_insert(Object->Signals, SignalName, SignalInfo);
1531 	}
1532 }
1533 
object_add_methods(object_t * Object,GIObjectInfo * Info)1534 static void object_add_methods(object_t *Object, GIObjectInfo *Info) {
1535 	object_add_signals(Object, Info);
1536 	GIObjectInfo *ParentInfo = g_object_info_get_parent(Info);
1537 	while (ParentInfo) {
1538 		object_add_signals(Object, ParentInfo);
1539 		ml_type_t *Parent = object_info_lookup(ParentInfo);
1540 		ml_type_add_parent((ml_type_t *)Object, Parent);
1541 		ParentInfo = g_object_info_get_parent(ParentInfo);
1542 	}
1543 	int NumInterfaces = g_object_info_get_n_interfaces(Info);
1544 	for (int I = 0; I < NumInterfaces; ++I) {
1545 		GIInterfaceInfo *InterfaceInfo = g_object_info_get_interface(Info, I);
1546 		ml_type_t *Interface = interface_info_lookup(InterfaceInfo);
1547 		ml_type_add_parent((ml_type_t *)Object, Interface);
1548 	}
1549 	int NumMethods = g_object_info_get_n_methods(Info);
1550 	for (int I = 0; I < NumMethods; ++I) {
1551 		GIFunctionInfo *MethodInfo = g_object_info_get_method(Info, I);
1552 		const char *MethodName = g_base_info_get_name((GIBaseInfo *)MethodInfo);
1553 		GIFunctionInfoFlags Flags = g_function_info_get_flags(MethodInfo);
1554 		if (Flags & GI_FUNCTION_IS_METHOD) {
1555 			ml_method_by_name(MethodName, MethodInfo, (ml_callback_t)method_invoke, Object, NULL);
1556 		} else if (Flags & GI_FUNCTION_IS_CONSTRUCTOR) {
1557 			stringmap_insert(Object->Base.Exports, MethodName, ml_cfunction(MethodInfo, (void *)constructor_invoke));
1558 		}
1559 	}
1560 }
1561 
1562 static stringmap_t TypeMap[1] = {STRINGMAP_INIT};
1563 
object_instance_new(object_t * Object,int Count,ml_value_t ** Args)1564 static ml_value_t *object_instance_new(object_t *Object, int Count, ml_value_t **Args) {
1565 	object_instance_t *Instance = new(object_instance_t);
1566 	Instance->Type = Object;
1567 	GType Type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)Object->Info);
1568 	if (Count > 0) {
1569 		ML_CHECK_ARG_TYPE(0, MLNamesT);
1570 		int NumProperties = Count - 1;
1571 		const char *Names[NumProperties];
1572 		GValue Values[NumProperties];
1573 		memset(Values, 0, NumProperties * sizeof(GValue));
1574 		int Index = 0;
1575 		ML_NAMES_FOREACH(Args[0], Iter) {
1576 			Names[Index] = ml_string_value(Iter->Value);
1577 			_ml_to_value(Args[Index + 1], Values + Index);
1578 		}
1579 		Instance->Handle = g_object_new_with_properties(Type, NumProperties, Names, Values);
1580 	} else {
1581 		Instance->Handle = g_object_new_with_properties(Type, 0, NULL, NULL);
1582 	}
1583 	g_object_set_qdata(Instance->Handle, MLQuark, Instance);
1584 	g_object_ref_sink(Instance->Handle);
1585 	GC_register_finalizer(Instance, (GC_finalization_proc)instance_finalize, 0, 0, 0);
1586 	return (ml_value_t *)Instance;
1587 }
1588 
object_info_lookup(GIObjectInfo * Info)1589 static ml_type_t *object_info_lookup(GIObjectInfo *Info) {
1590 	const char *TypeName = g_base_info_get_name((GIBaseInfo *)Info);
1591 	ml_type_t **Slot = (ml_type_t **)stringmap_slot(TypeMap, TypeName);
1592 	if (!Slot[0]) {
1593 		object_t *Object = new(object_t);
1594 		Object->Base.Type = ObjectT;
1595 		Object->Base.Name = TypeName;
1596 		Object->Base.hash = ml_default_hash;
1597 		Object->Base.call = ml_default_call;
1598 		Object->Base.deref = ml_default_deref;
1599 		Object->Base.assign = ml_default_assign;
1600 		Object->Info = Info;
1601 		ml_type_init((ml_type_t *)Object, ObjectInstanceT, NULL);
1602 		Object->Base.Constructor = ml_cfunction(Object, (ml_callback_t)object_instance_new);
1603 		object_add_methods(Object, Info);
1604 		Slot[0] = (ml_type_t *)Object;
1605 	}
1606 	return Slot[0];
1607 }
1608 
interface_info_lookup(GIInterfaceInfo * Info)1609 static ml_type_t *interface_info_lookup(GIInterfaceInfo *Info) {
1610 	const char *TypeName = g_base_info_get_name((GIBaseInfo *)Info);
1611 	ml_type_t **Slot = (ml_type_t **)stringmap_slot(TypeMap, TypeName);
1612 	if (!Slot[0]) {
1613 		object_t *Object = new(object_t);
1614 		Object->Base.Type = ObjectT;
1615 		Object->Base.Name = TypeName;
1616 		Object->Base.hash = ml_default_hash;
1617 		Object->Base.call = ml_default_call;
1618 		Object->Base.deref = ml_default_deref;
1619 		Object->Base.assign = ml_default_assign;
1620 		Object->Info = Info;
1621 		ml_type_init((ml_type_t *)Object, ObjectInstanceT, NULL);
1622 		Object->Base.Constructor = ml_cfunction(Object, (ml_callback_t)object_instance_new);
1623 		interface_add_methods(Object, Info);
1624 		Slot[0] = (ml_type_t *)Object;
1625 	}
1626 	return Slot[0];
1627 }
1628 
struct_info_lookup(GIStructInfo * Info)1629 static ml_type_t *struct_info_lookup(GIStructInfo *Info) {
1630 	const char *TypeName = g_base_info_get_name((GIBaseInfo *)Info);
1631 	ml_type_t **Slot = (ml_type_t **)stringmap_slot(TypeMap, TypeName);
1632 	if (!Slot[0]) {
1633 		struct_t *Struct = new(struct_t);
1634 		Struct->Base.Type = StructT;
1635 		Struct->Base.Name = TypeName;
1636 		Struct->Base.hash = ml_default_hash;
1637 		Struct->Base.call = ml_default_call;
1638 		Struct->Base.deref = ml_default_deref;
1639 		Struct->Base.assign = ml_default_assign;
1640 		Struct->Info = Info;
1641 		ml_type_init((ml_type_t *)Struct, StructInstanceT, NULL);
1642 		Struct->Base.Constructor = ml_cfunction(Struct, (void *)struct_instance_new);
1643 		Slot[0] = (ml_type_t *)Struct;
1644 		int NumFields = g_struct_info_get_n_fields(Info);
1645 		for (int I = 0; I < NumFields; ++I) {
1646 			GIFieldInfo *FieldInfo = g_struct_info_get_field(Info, I);
1647 			const char *FieldName = g_base_info_get_name((GIBaseInfo *)FieldInfo);
1648 			ml_method_by_name(FieldName, FieldInfo, (ml_callback_t)struct_field_ref, Struct, NULL);
1649 		}
1650 		int NumMethods = g_struct_info_get_n_methods(Info);
1651 		for (int I = 0; I < NumMethods; ++I) {
1652 			GIFunctionInfo *MethodInfo = g_struct_info_get_method(Info, I);
1653 			const char *MethodName = g_base_info_get_name((GIBaseInfo *)MethodInfo);
1654 			GIFunctionInfoFlags Flags = g_function_info_get_flags(MethodInfo);
1655 			if (Flags & GI_FUNCTION_IS_METHOD) {
1656 				ml_method_by_name(MethodName, MethodInfo, (ml_callback_t)method_invoke, Struct, NULL);
1657 			} else if (Flags & GI_FUNCTION_IS_CONSTRUCTOR) {
1658 				stringmap_insert(Struct->Base.Exports, MethodName, ml_cfunction(MethodInfo, (void *)constructor_invoke));
1659 			}
1660 		}
1661 	}
1662 	return Slot[0];
1663 }
1664 
1665 /*
1666 static void enum_iterate(ml_state_t *Caller, enum_t *Enum) {
1667 	return ml_iterate(Caller, Enum->ByIndex);
1668 }
1669 */
1670 
enum_info_lookup(GIEnumInfo * Info)1671 static ml_type_t *enum_info_lookup(GIEnumInfo *Info) {
1672 	const char *TypeName = g_base_info_get_name((GIBaseInfo *)Info);
1673 	ml_type_t **Slot = (ml_type_t **)stringmap_slot(TypeMap, TypeName);
1674 	if (!Slot[0]) {
1675 		int NumValues = g_enum_info_get_n_values(Info);
1676 		enum_t *Enum = xnew(enum_t, NumValues, ml_value_t *);
1677 		Enum->Base.Type = EnumT;
1678 		Enum->Base.Name = TypeName;
1679 		Enum->Base.hash = ml_default_hash;
1680 		Enum->Base.call = ml_default_call;
1681 		Enum->Base.deref = ml_default_deref;
1682 		Enum->Base.assign = ml_default_assign;
1683 		Enum->Base.Rank = EnumT->Rank + 1;
1684 		ml_type_init((ml_type_t *)Enum, EnumValueT, NULL);
1685 		for (int I = 0; I < NumValues; ++I) {
1686 			GIValueInfo *ValueInfo = g_enum_info_get_value(Info, I);
1687 			const char *ValueName = GC_strdup(g_base_info_get_name((GIBaseInfo *)ValueInfo));
1688 			enum_value_t *Value = new(enum_value_t);
1689 			Value->Type = Enum;
1690 			Value->Name = ml_cstring(ValueName);
1691 			Value->Value = g_value_info_get_value(ValueInfo);
1692 			stringmap_insert(Enum->Base.Exports, ValueName, (ml_value_t *)Value);
1693 			Enum->ByIndex[I] = (ml_value_t *)Value;
1694 		}
1695 		Enum->Info = Info;
1696 		Slot[0] = (ml_type_t *)Enum;
1697 	}
1698 	return Slot[0];
1699 }
1700 
constant_info_lookup(GIConstantInfo * Info)1701 static ml_value_t *constant_info_lookup(GIConstantInfo *Info) {
1702 	const char *TypeName = g_base_info_get_name((GIBaseInfo *)Info);
1703 	ml_value_t **Slot = (ml_value_t **)stringmap_slot(TypeMap, TypeName);
1704 	if (!Slot[0]) {
1705 		GIArgument Argument[1];
1706 		g_constant_info_get_value(Info, Argument);
1707 		ml_value_t *Value = argument_to_ml(Argument, g_constant_info_get_type(Info), NULL, NULL);
1708 		Slot[0] = Value;
1709 	}
1710 	return Slot[0];
1711 }
1712 
baseinfo_to_value(GIBaseInfo * Info)1713 static ml_value_t *baseinfo_to_value(GIBaseInfo *Info) {
1714 	switch (g_base_info_get_type(Info)) {
1715 	case GI_INFO_TYPE_INVALID:
1716 	case GI_INFO_TYPE_INVALID_0: {
1717 		break;
1718 	}
1719 	case GI_INFO_TYPE_FUNCTION: {
1720 		return ml_cfunction(Info, (ml_callback_t)function_info_invoke);
1721 	}
1722 	case GI_INFO_TYPE_CALLBACK: {
1723 		break;
1724 	}
1725 	case GI_INFO_TYPE_STRUCT: {
1726 		return (ml_value_t *)struct_info_lookup((GIStructInfo *)Info);
1727 	}
1728 	case GI_INFO_TYPE_BOXED: {
1729 		break;
1730 	}
1731 	case GI_INFO_TYPE_ENUM: {
1732 		return (ml_value_t *)enum_info_lookup((GIEnumInfo *)Info);
1733 	}
1734 	case GI_INFO_TYPE_FLAGS: {
1735 		return (ml_value_t *)enum_info_lookup((GIEnumInfo *)Info);
1736 	}
1737 	case GI_INFO_TYPE_OBJECT: {
1738 		return (ml_value_t *)object_info_lookup((GIObjectInfo *)Info);
1739 	}
1740 	case GI_INFO_TYPE_INTERFACE: {
1741 		break;
1742 	}
1743 	case GI_INFO_TYPE_CONSTANT: {
1744 		return constant_info_lookup((GIConstantInfo *)Info);
1745 	}
1746 	case GI_INFO_TYPE_UNION: {
1747 		break;
1748 	}
1749 	case GI_INFO_TYPE_VALUE: {
1750 		break;
1751 	}
1752 	case GI_INFO_TYPE_SIGNAL: {
1753 		break;
1754 	}
1755 	case GI_INFO_TYPE_VFUNC: {
1756 		break;
1757 	}
1758 	case GI_INFO_TYPE_PROPERTY: {
1759 		break;
1760 	}
1761 	case GI_INFO_TYPE_FIELD: {
1762 		break;
1763 	}
1764 	case GI_INFO_TYPE_ARG: {
1765 		break;
1766 	}
1767 	case GI_INFO_TYPE_TYPE: {
1768 		break;
1769 	}
1770 	case GI_INFO_TYPE_UNRESOLVED: {
1771 		break;
1772 	}
1773 	}
1774 	printf("Unsupported info type: %s\n", g_info_type_to_string(g_base_info_get_type(Info)));
1775 	return MLNil;
1776 }
1777 
1778 ML_METHOD("::", TypelibT, MLStringT) {
1779 //<Typelib
1780 //<Name
1781 //>any | error
1782 	typelib_t *Typelib = (typelib_t *)Args[0];
1783 	const char *Name = ml_string_value(Args[1]);
1784 	GIBaseInfo *Info = g_irepository_find_by_name(NULL, Typelib->Namespace, Name);
1785 	if (!Info) {
1786 		return ml_error("NameError", "Symbol %s not found in %s", Name, Typelib->Namespace);
1787 	} else {
1788 		return baseinfo_to_value(Info);
1789 	}
1790 }
1791 
typelib_iterate(ml_state_t * Caller,typelib_t * Typelib)1792 static void typelib_iterate(ml_state_t *Caller, typelib_t *Typelib) {
1793 	typelib_iter_t *Iter = new(typelib_iter_t);
1794 	Iter->Type = TypelibIterT;
1795 	Iter->Namespace = Typelib->Namespace;
1796 	Iter->Handle = Typelib->Handle;
1797 	Iter->Index = 0;
1798 	Iter->Total = g_irepository_get_n_infos(NULL, Iter->Namespace);
1799 	Iter->Current = g_irepository_get_info(NULL, Iter->Namespace, 0);
1800 	ML_CONTINUE(Caller, Iter);
1801 }
1802 
_value_to_ml(const GValue * Value,GIBaseInfo * Info)1803 static ml_value_t *_value_to_ml(const GValue *Value, GIBaseInfo *Info) {
1804 	switch (G_VALUE_TYPE(Value)) {
1805 	case G_TYPE_NONE: return MLNil;
1806 	case G_TYPE_CHAR: return ml_integer(g_value_get_schar(Value));
1807 	case G_TYPE_UCHAR: return ml_integer(g_value_get_uchar(Value));
1808 	case G_TYPE_BOOLEAN: return ml_boolean(g_value_get_boolean(Value));
1809 	case G_TYPE_INT: return ml_integer(g_value_get_int(Value));
1810 	case G_TYPE_UINT: return ml_integer(g_value_get_uint(Value));
1811 	case G_TYPE_LONG: return ml_integer(g_value_get_long(Value));
1812 	case G_TYPE_ULONG: return ml_integer(g_value_get_ulong(Value));
1813 	case G_TYPE_ENUM: {
1814 		GType Type = G_VALUE_TYPE(Value);
1815 		GIBaseInfo *Info = g_irepository_find_by_gtype(NULL, Type);
1816 		enum_t *Enum = (enum_t *)enum_info_lookup((GIEnumInfo *)Info);
1817 		return Enum->ByIndex[g_value_get_enum(Value)];
1818 	}
1819 	case G_TYPE_FLAGS: return ml_integer(g_value_get_flags(Value));
1820 	case G_TYPE_FLOAT: return ml_real(g_value_get_float(Value));
1821 	case G_TYPE_DOUBLE: return ml_real(g_value_get_double(Value));
1822 	case G_TYPE_STRING: return ml_string(g_value_get_string(Value), -1);
1823 	case G_TYPE_POINTER: return MLNil; //Std$Address$new(g_value_get_pointer(Value));
1824 	default: {
1825 		if (G_VALUE_HOLDS(Value, G_TYPE_OBJECT)) {
1826 			return ml_gir_instance_get(g_value_get_object(Value), Info);
1827 		} else {
1828 			GIBaseInfo *InterfaceInfo = g_irepository_find_by_gtype(NULL, G_VALUE_TYPE(Value));
1829 			if (InterfaceInfo) {
1830 				switch (g_base_info_get_type(InterfaceInfo)) {
1831 				case GI_INFO_TYPE_INVALID:
1832 				case GI_INFO_TYPE_INVALID_0: break;
1833 				case GI_INFO_TYPE_FUNCTION: break;
1834 				case GI_INFO_TYPE_CALLBACK: break;
1835 				case GI_INFO_TYPE_STRUCT: {
1836 					struct_instance_t *Instance = new(struct_instance_t);
1837 					Instance->Type = (struct_t *)struct_info_lookup((GIStructInfo *)InterfaceInfo);
1838 					Instance->Value = g_value_get_boxed(Value);
1839 					return (ml_value_t *)Instance;
1840 				}
1841 				case GI_INFO_TYPE_BOXED: {
1842 					break;
1843 				}
1844 				case GI_INFO_TYPE_ENUM: {
1845 					enum_t *Enum = (enum_t *)enum_info_lookup((GIEnumInfo *)InterfaceInfo);
1846 					return Enum->ByIndex[g_value_get_uint(Value)];
1847 				}
1848 				case GI_INFO_TYPE_FLAGS: {
1849 					break;
1850 				}
1851 				case GI_INFO_TYPE_OBJECT:
1852 				case GI_INFO_TYPE_INTERFACE: {
1853 					return ml_gir_instance_get(g_value_get_pointer(Value), InterfaceInfo);
1854 					break;
1855 				}
1856 				case GI_INFO_TYPE_CONSTANT: {
1857 					break;
1858 				}
1859 				case GI_INFO_TYPE_UNION: {
1860 					break;
1861 				}
1862 				case GI_INFO_TYPE_VALUE: {
1863 					break;
1864 				}
1865 				case GI_INFO_TYPE_SIGNAL: {
1866 					break;
1867 				}
1868 				case GI_INFO_TYPE_VFUNC: {
1869 					break;
1870 				}
1871 				case GI_INFO_TYPE_PROPERTY: {
1872 					break;
1873 				}
1874 				case GI_INFO_TYPE_FIELD: {
1875 					break;
1876 				}
1877 				case GI_INFO_TYPE_ARG: {
1878 					break;
1879 				}
1880 				case GI_INFO_TYPE_TYPE: {
1881 					break;
1882 				}
1883 				case GI_INFO_TYPE_UNRESOLVED: {
1884 					break;
1885 				}
1886 				}
1887 			}
1888 			printf("Warning: Unknown parameter type: %s\n", G_VALUE_TYPE_NAME(Value));
1889 			return MLNil;
1890 		}
1891 	}
1892 	}
1893 }
1894 
_ml_to_value(ml_value_t * Source,GValue * Dest)1895 static void _ml_to_value(ml_value_t *Source, GValue *Dest) {
1896 	if (Source == MLNil) {
1897 		g_value_init(Dest, G_TYPE_NONE);
1898 	} else if (ml_is(Source, MLBooleanT)) {
1899 		g_value_init(Dest, G_TYPE_BOOLEAN);
1900 		g_value_set_boolean(Dest, ml_boolean_value(Source));
1901 	} else if (ml_is(Source, MLIntegerT)) {
1902 		g_value_init(Dest, G_TYPE_LONG);
1903 		g_value_set_long(Dest, ml_integer_value(Source));
1904 	} else if (ml_is(Source, MLDoubleT)) {
1905 		g_value_init(Dest, G_TYPE_DOUBLE);
1906 		g_value_set_double(Dest, ml_real_value(Source));
1907 	} else if (ml_is(Source, MLStringT)) {
1908 		g_value_init(Dest, G_TYPE_STRING);
1909 		g_value_set_string(Dest, ml_string_value(Source));
1910 	} else if (ml_is(Source, ObjectInstanceT)) {
1911 		void *Object = ((object_instance_t *)Source)->Handle;
1912 		g_value_init(Dest, G_OBJECT_TYPE(Object));
1913 		g_value_set_object(Dest, Object);
1914 	} else if (ml_is(Source, StructInstanceT)) {
1915 		void *Value = ((struct_instance_t *)Source)->Value;
1916 		g_value_init(Dest, G_TYPE_POINTER);
1917 		g_value_set_object(Dest, Value);
1918 	} else if (ml_is(Source, EnumValueT)) {
1919 		enum_t *Enum = (enum_t *)((enum_value_t *)Source)->Type;
1920 		GType Type = g_type_from_name(g_base_info_get_name((GIBaseInfo *)Enum->Info));
1921 		g_value_init(Dest, Type);
1922 		g_value_set_enum(Dest, ((enum_value_t *)Source)->Value);
1923 	} else {
1924 		g_value_init(Dest, G_TYPE_NONE);
1925 	}
1926 }
1927 
__marshal(GClosure * Closure,GValue * Dest,guint NumArgs,const GValue * Args,gpointer Hint,ml_value_t * Function)1928 static void __marshal(GClosure *Closure, GValue *Dest, guint NumArgs, const GValue *Args, gpointer Hint, ml_value_t *Function) {
1929 	GICallableInfo *SignalInfo = (GICallableInfo *)Closure->data;
1930 	ml_value_t *MLArgs[NumArgs];
1931 	MLArgs[0] = _value_to_ml(Args, NULL);
1932 	for (guint I = 1; I < NumArgs; ++I) {
1933 		GIArgInfo *ArgInfo = g_callable_info_get_arg(SignalInfo, I - 1);
1934 		GITypeInfo TypeInfo[1];
1935 		g_arg_info_load_type(ArgInfo, TypeInfo);
1936 		MLArgs[I] = _value_to_ml(Args + I, g_type_info_get_interface(TypeInfo));
1937 	}
1938 	ml_value_t *Source = ml_simple_call(Function, NumArgs, MLArgs);
1939 	if (Dest) {
1940 		if (ml_is(Source, MLBooleanT)) {
1941 			g_value_set_boolean(Dest, ml_boolean_value(Source));
1942 		} else if (ml_is(Source, MLIntegerT)) {
1943 			g_value_set_long(Dest, ml_integer_value(Source));
1944 		} else if (ml_is(Source, MLDoubleT)) {
1945 			g_value_set_double(Dest, ml_real_value(Source));
1946 		} else if (ml_is(Source, MLStringT)) {
1947 			g_value_set_string(Dest, ml_string_value(Source));
1948 		} else if (ml_is(Source, ObjectInstanceT)) {
1949 			void *Object = ((object_instance_t *)Source)->Handle;
1950 			g_value_set_object(Dest, Object);
1951 		} else if (ml_is(Source, StructInstanceT)) {
1952 			void *Value = ((struct_instance_t *)Source)->Value;
1953 			g_value_set_object(Dest, Value);
1954 		} else if (ml_is(Source, EnumValueT)) {
1955 			enum_t *Enum = (enum_t *)((enum_value_t *)Source)->Type;
1956 			GType Type = g_type_from_name(g_base_info_get_name((GIBaseInfo *)Enum->Info));
1957 			g_value_init(Dest, Type);
1958 			g_value_set_enum(Dest, ((enum_value_t *)Source)->Value);
1959 		}
1960 	}
1961 }
1962 
1963 ML_METHOD("connect", ObjectInstanceT, MLStringT, MLFunctionT) {
1964 //<Object
1965 //<Signal
1966 //<Handler
1967 //>Object
1968 	object_instance_t *Instance = (object_instance_t *)Args[0];
1969 	const char *Signal = ml_string_value(Args[1]);
1970 	GISignalInfo *SignalInfo = (GISignalInfo *)stringmap_search(Instance->Type->Signals, Signal);
1971 	if (!SignalInfo) return ml_error("NameError", "Signal %s not found", Signal);
1972 	GClosure *Closure = g_closure_new_simple(sizeof(GClosure), SignalInfo);
1973 	g_closure_set_meta_marshal(Closure, Args[2], (GClosureMarshal)__marshal);
1974 	g_signal_connect_closure(Instance->Handle, Signal, Closure, Count > 3 && Args[3] != MLNil);
1975 	return Args[0];
1976 }
1977 
1978 typedef struct {
1979 	ml_type_t *Type;
1980 	GObject *Object;
1981 	const char *Name;
1982 } object_property_t;
1983 
object_property_deref(object_property_t * Property)1984 static ml_value_t *object_property_deref(object_property_t *Property) {
1985 	GValue Value[1] = {G_VALUE_INIT};
1986 	g_object_get_property(Property->Object, Property->Name, Value);
1987 	if (G_VALUE_TYPE(Value) == 0) {
1988 		return ml_error("PropertyError", "Invalid property %s", Property->Name);
1989 	}
1990 	return _value_to_ml(Value, NULL);
1991 }
1992 
object_property_assign(object_property_t * Property,ml_value_t * Value0)1993 static ml_value_t *object_property_assign(object_property_t *Property, ml_value_t *Value0) {
1994 	GValue Value[1];
1995 	memset(Value, 0, sizeof(GValue));
1996 	_ml_to_value(Value0, Value);
1997 	g_object_set_property(Property->Object, Property->Name, Value);
1998 	return Value0;
1999 }
2000 
2001 ML_TYPE(ObjectPropertyT, (), "gir-object-property",
2002 	.deref = (void *)object_property_deref,
2003 	.assign = (void *)object_property_assign
2004 );
2005 
2006 ML_METHOD("::", ObjectInstanceT, MLStringT) {
2007 //<Object
2008 //<Property
2009 //>any
2010 	object_instance_t *Instance = (object_instance_t *)Args[0];
2011 	object_property_t *Property = new(object_property_t);
2012 	Property->Type = ObjectPropertyT;
2013 	Property->Object = Instance->Handle;
2014 	Property->Name = ml_string_value(Args[1]);
2015 	return (ml_value_t *)Property;
2016 }
2017 
ml_gir_init(stringmap_t * Globals)2018 void ml_gir_init(stringmap_t *Globals) {
2019 	GError *Error = 0;
2020 	g_irepository_require(NULL, "GLib", NULL, 0, &Error);
2021 	g_irepository_require(NULL, "GObject", NULL, 0, &Error);
2022 	DestroyNotifyInfo = g_irepository_find_by_name(NULL, "GLib", "DestroyNotify");
2023 	GValueInfo = g_irepository_find_by_name(NULL, "GObject", "Value");
2024 	ml_typed_fn_set(TypelibT, ml_iterate, typelib_iterate);
2025 	ml_typed_fn_set(TypelibIterT, ml_iter_next, typelib_iter_next);
2026 	ml_typed_fn_set(TypelibIterT, ml_iter_value, typelib_iter_value);
2027 	ml_typed_fn_set(TypelibIterT, ml_iter_key, typelib_iter_key);
2028 	MLQuark = g_quark_from_static_string("<<minilang>>");
2029 	ObjectInstanceNil = new(object_instance_t);
2030 	ObjectInstanceNil->Type = (object_t *)ObjectInstanceT;
2031 	//ml_typed_fn_set(EnumT, ml_iterate, enum_iterate);
2032 	stringmap_insert(Globals, "gir", MLGir);
2033 	ObjectT->call = MLTypeT->call;
2034 	StructT->call = MLTypeT->call;
2035 #include "ml_gir_init.c"
2036 }
2037