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