Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : * GObject introspection: Typelib creation
3 : : *
4 : : * Copyright (C) 2005 Matthias Clasen
5 : : * Copyright (C) 2008,2009 Red Hat, Inc.
6 : : *
7 : : * SPDX-License-Identifier: LGPL-2.1-or-later
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2 of the License, or (at your option) any later version.
13 : : *
14 : : * This library is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General Public
20 : : * License along with this library; if not, write to the
21 : : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 : : * Boston, MA 02111-1307, USA.
23 : : */
24 : :
25 : : #include "config.h"
26 : :
27 : : #include "girnode-private.h"
28 : : #include "girepository-private.h"
29 : : #include "gitypelib-internal.h"
30 : :
31 : : #include <stdio.h>
32 : : #include <stdlib.h>
33 : : #include <string.h>
34 : :
35 : : #ifdef _MSC_VER
36 : : #define strtoll _strtoi64
37 : : #define strtoull _strtoui64
38 : : #endif
39 : :
40 : : static gulong string_count = 0;
41 : : static gulong unique_string_count = 0;
42 : : static gulong string_size = 0;
43 : : static gulong unique_string_size = 0;
44 : : static gulong types_count = 0;
45 : : static gulong unique_types_count = 0;
46 : :
47 : : void
48 : 0 : gi_ir_node_init_stats (void)
49 : : {
50 : 0 : string_count = 0;
51 : 0 : unique_string_count = 0;
52 : 0 : string_size = 0;
53 : 0 : unique_string_size = 0;
54 : 0 : types_count = 0;
55 : 0 : unique_types_count = 0;
56 : 0 : }
57 : :
58 : : void
59 : 0 : gi_ir_node_dump_stats (void)
60 : : {
61 : 0 : g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
62 : : unique_string_count, string_count, unique_string_size, string_size);
63 : 0 : g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
64 : 0 : }
65 : :
66 : : #define DO_ALIGNED_COPY(dest_addr, value, type) \
67 : : do { \
68 : : type tmp_var; \
69 : : tmp_var = value; \
70 : : memcpy(dest_addr, &tmp_var, sizeof(type)); \
71 : : } while(0)
72 : :
73 : : #define ALIGN_VALUE(this, boundary) \
74 : : (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
75 : :
76 : :
77 : : const char *
78 : 0 : gi_ir_node_type_to_string (GIIrNodeTypeId type)
79 : : {
80 [ # # # # : 0 : switch (type)
# # # # #
# # # # #
# # # #
# ]
81 : : {
82 : 0 : case GI_IR_NODE_FUNCTION:
83 : 0 : return "function";
84 : 0 : case GI_IR_NODE_CALLBACK:
85 : 0 : return "callback";
86 : 0 : case GI_IR_NODE_PARAM:
87 : 0 : return "param";
88 : 0 : case GI_IR_NODE_TYPE:
89 : 0 : return "type";
90 : 0 : case GI_IR_NODE_OBJECT:
91 : 0 : return "object";
92 : 0 : case GI_IR_NODE_INTERFACE:
93 : 0 : return "interface";
94 : 0 : case GI_IR_NODE_SIGNAL:
95 : 0 : return "signal";
96 : 0 : case GI_IR_NODE_PROPERTY:
97 : 0 : return "property";
98 : 0 : case GI_IR_NODE_VFUNC:
99 : 0 : return "vfunc";
100 : 0 : case GI_IR_NODE_FIELD:
101 : 0 : return "field";
102 : 0 : case GI_IR_NODE_ENUM:
103 : 0 : return "enum";
104 : 0 : case GI_IR_NODE_FLAGS:
105 : 0 : return "flags";
106 : 0 : case GI_IR_NODE_BOXED:
107 : 0 : return "boxed";
108 : 0 : case GI_IR_NODE_STRUCT:
109 : 0 : return "struct";
110 : 0 : case GI_IR_NODE_VALUE:
111 : 0 : return "value";
112 : 0 : case GI_IR_NODE_CONSTANT:
113 : 0 : return "constant";
114 : 0 : case GI_IR_NODE_XREF:
115 : 0 : return "xref";
116 : 0 : case GI_IR_NODE_UNION:
117 : 0 : return "union";
118 : 0 : default:
119 : 0 : return "unknown";
120 : : }
121 : : }
122 : :
123 : : GIIrNode *
124 : 0 : gi_ir_node_new (GIIrNodeTypeId type,
125 : : GIIrModule *module)
126 : : {
127 : 0 : GIIrNode *node = NULL;
128 : :
129 [ # # # # : 0 : switch (type)
# # # # #
# # # # #
# # ]
130 : : {
131 : 0 : case GI_IR_NODE_FUNCTION:
132 : : case GI_IR_NODE_CALLBACK:
133 : 0 : node = g_malloc0 (sizeof (GIIrNodeFunction));
134 : 0 : break;
135 : :
136 : 0 : case GI_IR_NODE_PARAM:
137 : 0 : node = g_malloc0 (sizeof (GIIrNodeParam));
138 : 0 : break;
139 : :
140 : 0 : case GI_IR_NODE_TYPE:
141 : 0 : node = g_malloc0 (sizeof (GIIrNodeType));
142 : 0 : break;
143 : :
144 : 0 : case GI_IR_NODE_OBJECT:
145 : : case GI_IR_NODE_INTERFACE:
146 : 0 : node = g_malloc0 (sizeof (GIIrNodeInterface));
147 : 0 : break;
148 : :
149 : 0 : case GI_IR_NODE_SIGNAL:
150 : 0 : node = g_malloc0 (sizeof (GIIrNodeSignal));
151 : 0 : break;
152 : :
153 : 0 : case GI_IR_NODE_PROPERTY:
154 : 0 : node = g_malloc0 (sizeof (GIIrNodeProperty));
155 : 0 : break;
156 : :
157 : 0 : case GI_IR_NODE_VFUNC:
158 : 0 : node = g_malloc0 (sizeof (GIIrNodeFunction));
159 : 0 : break;
160 : :
161 : 0 : case GI_IR_NODE_FIELD:
162 : 0 : node = g_malloc0 (sizeof (GIIrNodeField));
163 : 0 : break;
164 : :
165 : 0 : case GI_IR_NODE_ENUM:
166 : : case GI_IR_NODE_FLAGS:
167 : 0 : node = g_malloc0 (sizeof (GIIrNodeEnum));
168 : 0 : break;
169 : :
170 : 0 : case GI_IR_NODE_BOXED:
171 : 0 : node = g_malloc0 (sizeof (GIIrNodeBoxed));
172 : 0 : break;
173 : :
174 : 0 : case GI_IR_NODE_STRUCT:
175 : 0 : node = g_malloc0 (sizeof (GIIrNodeStruct));
176 : 0 : break;
177 : :
178 : 0 : case GI_IR_NODE_VALUE:
179 : 0 : node = g_malloc0 (sizeof (GIIrNodeValue));
180 : 0 : break;
181 : :
182 : 0 : case GI_IR_NODE_CONSTANT:
183 : 0 : node = g_malloc0 (sizeof (GIIrNodeConstant));
184 : 0 : break;
185 : :
186 : 0 : case GI_IR_NODE_XREF:
187 : 0 : node = g_malloc0 (sizeof (GIIrNodeXRef));
188 : 0 : break;
189 : :
190 : 0 : case GI_IR_NODE_UNION:
191 : 0 : node = g_malloc0 (sizeof (GIIrNodeUnion));
192 : 0 : break;
193 : :
194 : 0 : default:
195 : 0 : g_error ("Unhandled node type %d", type);
196 : : break;
197 : : }
198 : :
199 : 0 : node->type = type;
200 : 0 : node->module = module;
201 : 0 : node->offset = 0;
202 : 0 : node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
203 : : g_free, g_free);
204 : :
205 : 0 : return node;
206 : : }
207 : :
208 : : void
209 : 0 : gi_ir_node_free (GIIrNode *node)
210 : : {
211 : : GList *l;
212 : :
213 [ # # ]: 0 : if (node == NULL)
214 : 0 : return;
215 : :
216 [ # # # # : 0 : switch (node->type)
# # # # #
# # # # #
# # ]
217 : : {
218 : 0 : case GI_IR_NODE_FUNCTION:
219 : : case GI_IR_NODE_CALLBACK:
220 : : {
221 : 0 : GIIrNodeFunction *function = (GIIrNodeFunction *)node;
222 : :
223 : 0 : g_free (node->name);
224 : 0 : g_free (function->symbol);
225 : 0 : g_free (function->property);
226 : 0 : gi_ir_node_free ((GIIrNode *)function->result);
227 [ # # ]: 0 : for (l = function->parameters; l; l = l->next)
228 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
229 : 0 : g_list_free (function->parameters);
230 : : }
231 : 0 : break;
232 : :
233 : 0 : case GI_IR_NODE_TYPE:
234 : : {
235 : 0 : GIIrNodeType *type = (GIIrNodeType *)node;
236 : :
237 : 0 : g_free (node->name);
238 : 0 : gi_ir_node_free ((GIIrNode *)type->parameter_type1);
239 : 0 : gi_ir_node_free ((GIIrNode *)type->parameter_type2);
240 : :
241 : 0 : g_free (type->giinterface);
242 : 0 : g_strfreev (type->errors);
243 : 0 : g_free (type->unparsed);
244 : : }
245 : 0 : break;
246 : :
247 : 0 : case GI_IR_NODE_PARAM:
248 : : {
249 : 0 : GIIrNodeParam *param = (GIIrNodeParam *)node;
250 : :
251 : 0 : g_free (node->name);
252 : 0 : gi_ir_node_free ((GIIrNode *)param->type);
253 : : }
254 : 0 : break;
255 : :
256 : 0 : case GI_IR_NODE_PROPERTY:
257 : : {
258 : 0 : GIIrNodeProperty *property = (GIIrNodeProperty *)node;
259 : :
260 : 0 : g_free (node->name);
261 : 0 : g_free (property->setter);
262 : 0 : g_free (property->getter);
263 : 0 : gi_ir_node_free ((GIIrNode *)property->type);
264 : : }
265 : 0 : break;
266 : :
267 : 0 : case GI_IR_NODE_SIGNAL:
268 : : {
269 : 0 : GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
270 : :
271 : 0 : g_free (node->name);
272 [ # # ]: 0 : for (l = signal->parameters; l; l = l->next)
273 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
274 : 0 : g_list_free (signal->parameters);
275 : 0 : gi_ir_node_free ((GIIrNode *)signal->result);
276 : : }
277 : 0 : break;
278 : :
279 : 0 : case GI_IR_NODE_VFUNC:
280 : : {
281 : 0 : GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
282 : :
283 : 0 : g_free (node->name);
284 : 0 : g_free (vfunc->invoker);
285 [ # # ]: 0 : for (l = vfunc->parameters; l; l = l->next)
286 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
287 : 0 : g_list_free (vfunc->parameters);
288 : 0 : gi_ir_node_free ((GIIrNode *)vfunc->result);
289 : : }
290 : 0 : break;
291 : :
292 : 0 : case GI_IR_NODE_FIELD:
293 : : {
294 : 0 : GIIrNodeField *field = (GIIrNodeField *)node;
295 : :
296 : 0 : g_free (node->name);
297 : 0 : gi_ir_node_free ((GIIrNode *)field->type);
298 : 0 : gi_ir_node_free ((GIIrNode *)field->callback);
299 : : }
300 : 0 : break;
301 : :
302 : 0 : case GI_IR_NODE_OBJECT:
303 : : case GI_IR_NODE_INTERFACE:
304 : : {
305 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
306 : :
307 : 0 : g_free (node->name);
308 : 0 : g_free (iface->gtype_name);
309 : 0 : g_free (iface->gtype_init);
310 : 0 : g_free (iface->ref_func);
311 : 0 : g_free (iface->unref_func);
312 : 0 : g_free (iface->set_value_func);
313 : 0 : g_free (iface->get_value_func);
314 : :
315 : :
316 : 0 : g_free (iface->glib_type_struct);
317 : 0 : g_free (iface->parent);
318 : :
319 [ # # ]: 0 : for (l = iface->interfaces; l; l = l->next)
320 : 0 : g_free ((GIIrNode *)l->data);
321 : 0 : g_list_free (iface->interfaces);
322 : :
323 : 0 : g_list_free_full (iface->prerequisites, g_free);
324 : :
325 [ # # ]: 0 : for (l = iface->members; l; l = l->next)
326 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
327 : 0 : g_list_free (iface->members);
328 : :
329 : : }
330 : 0 : break;
331 : :
332 : 0 : case GI_IR_NODE_VALUE:
333 : : {
334 : 0 : g_free (node->name);
335 : : }
336 : 0 : break;
337 : :
338 : 0 : case GI_IR_NODE_ENUM:
339 : : case GI_IR_NODE_FLAGS:
340 : : {
341 : 0 : GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
342 : :
343 : 0 : g_free (node->name);
344 : 0 : g_free (enum_->gtype_name);
345 : 0 : g_free (enum_->gtype_init);
346 : 0 : g_free (enum_->error_domain);
347 : :
348 [ # # ]: 0 : for (l = enum_->values; l; l = l->next)
349 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
350 : 0 : g_list_free (enum_->values);
351 : :
352 [ # # ]: 0 : for (l = enum_->methods; l; l = l->next)
353 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
354 : 0 : g_list_free (enum_->methods);
355 : : }
356 : 0 : break;
357 : :
358 : 0 : case GI_IR_NODE_BOXED:
359 : : {
360 : 0 : GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
361 : :
362 : 0 : g_free (node->name);
363 : 0 : g_free (boxed->gtype_name);
364 : 0 : g_free (boxed->gtype_init);
365 : :
366 [ # # ]: 0 : for (l = boxed->members; l; l = l->next)
367 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
368 : 0 : g_list_free (boxed->members);
369 : : }
370 : 0 : break;
371 : :
372 : 0 : case GI_IR_NODE_STRUCT:
373 : : {
374 : 0 : GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
375 : :
376 : 0 : g_free (node->name);
377 : 0 : g_free (struct_->gtype_name);
378 : 0 : g_free (struct_->gtype_init);
379 : 0 : g_free (struct_->copy_func);
380 : 0 : g_free (struct_->free_func);
381 : :
382 [ # # ]: 0 : for (l = struct_->members; l; l = l->next)
383 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
384 : 0 : g_list_free (struct_->members);
385 : : }
386 : 0 : break;
387 : :
388 : 0 : case GI_IR_NODE_CONSTANT:
389 : : {
390 : 0 : GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
391 : :
392 : 0 : g_free (node->name);
393 : 0 : g_free (constant->value);
394 : 0 : gi_ir_node_free ((GIIrNode *)constant->type);
395 : : }
396 : 0 : break;
397 : :
398 : 0 : case GI_IR_NODE_XREF:
399 : : {
400 : 0 : GIIrNodeXRef *xref = (GIIrNodeXRef *)node;
401 : :
402 : 0 : g_free (node->name);
403 : 0 : g_free (xref->namespace);
404 : : }
405 : 0 : break;
406 : :
407 : 0 : case GI_IR_NODE_UNION:
408 : : {
409 : 0 : GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
410 : :
411 : 0 : g_free (node->name);
412 : 0 : g_free (union_->gtype_name);
413 : 0 : g_free (union_->gtype_init);
414 : 0 : g_free (union_->copy_func);
415 : 0 : g_free (union_->free_func);
416 : :
417 : 0 : gi_ir_node_free ((GIIrNode *)union_->discriminator_type);
418 [ # # ]: 0 : for (l = union_->members; l; l = l->next)
419 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
420 [ # # ]: 0 : for (l = union_->discriminators; l; l = l->next)
421 : 0 : gi_ir_node_free ((GIIrNode *)l->data);
422 : : }
423 : 0 : break;
424 : :
425 : 0 : default:
426 : 0 : g_error ("Unhandled node type %d", node->type);
427 : : break;
428 : : }
429 : :
430 : 0 : g_hash_table_destroy (node->attributes);
431 : :
432 : 0 : g_free (node);
433 : : }
434 : :
435 : : /* returns the fixed size of the blob */
436 : : uint32_t
437 : 0 : gi_ir_node_get_size (GIIrNode *node)
438 : : {
439 : : GList *l;
440 : : size_t size, n;
441 : :
442 [ # # # # : 0 : switch (node->type)
# # # # #
# # # # #
# # # # ]
443 : : {
444 : 0 : case GI_IR_NODE_CALLBACK:
445 : 0 : size = sizeof (CallbackBlob);
446 : 0 : break;
447 : :
448 : 0 : case GI_IR_NODE_FUNCTION:
449 : 0 : size = sizeof (FunctionBlob);
450 : 0 : break;
451 : :
452 : 0 : case GI_IR_NODE_PARAM:
453 : : /* See the comment in the GI_IR_NODE_PARAM/ArgBlob writing below */
454 : 0 : size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
455 : 0 : break;
456 : :
457 : 0 : case GI_IR_NODE_TYPE:
458 : 0 : size = sizeof (SimpleTypeBlob);
459 : 0 : break;
460 : :
461 : 0 : case GI_IR_NODE_OBJECT:
462 : : {
463 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
464 : :
465 : 0 : n = g_list_length (iface->interfaces);
466 : 0 : size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
467 : :
468 [ # # ]: 0 : for (l = iface->members; l; l = l->next)
469 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
470 : : }
471 : 0 : break;
472 : :
473 : 0 : case GI_IR_NODE_INTERFACE:
474 : : {
475 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
476 : :
477 : 0 : n = g_list_length (iface->prerequisites);
478 : 0 : size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
479 : :
480 [ # # ]: 0 : for (l = iface->members; l; l = l->next)
481 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
482 : : }
483 : 0 : break;
484 : :
485 : 0 : case GI_IR_NODE_ENUM:
486 : : case GI_IR_NODE_FLAGS:
487 : : {
488 : 0 : GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
489 : :
490 : 0 : size = sizeof (EnumBlob);
491 [ # # ]: 0 : for (l = enum_->values; l; l = l->next)
492 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
493 [ # # ]: 0 : for (l = enum_->methods; l; l = l->next)
494 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
495 : : }
496 : 0 : break;
497 : :
498 : 0 : case GI_IR_NODE_VALUE:
499 : 0 : size = sizeof (ValueBlob);
500 : 0 : break;
501 : :
502 : 0 : case GI_IR_NODE_STRUCT:
503 : : {
504 : 0 : GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
505 : :
506 : 0 : size = sizeof (StructBlob);
507 [ # # ]: 0 : for (l = struct_->members; l; l = l->next)
508 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
509 : : }
510 : 0 : break;
511 : :
512 : 0 : case GI_IR_NODE_BOXED:
513 : : {
514 : 0 : GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
515 : :
516 : 0 : size = sizeof (StructBlob);
517 [ # # ]: 0 : for (l = boxed->members; l; l = l->next)
518 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
519 : : }
520 : 0 : break;
521 : :
522 : 0 : case GI_IR_NODE_PROPERTY:
523 : 0 : size = sizeof (PropertyBlob);
524 : 0 : break;
525 : :
526 : 0 : case GI_IR_NODE_SIGNAL:
527 : 0 : size = sizeof (SignalBlob);
528 : 0 : break;
529 : :
530 : 0 : case GI_IR_NODE_VFUNC:
531 : 0 : size = sizeof (VFuncBlob);
532 : 0 : break;
533 : :
534 : 0 : case GI_IR_NODE_FIELD:
535 : : {
536 : 0 : GIIrNodeField *field = (GIIrNodeField *)node;
537 : :
538 : 0 : size = sizeof (FieldBlob);
539 [ # # ]: 0 : if (field->callback)
540 : 0 : size += gi_ir_node_get_size ((GIIrNode *)field->callback);
541 : : }
542 : 0 : break;
543 : :
544 : 0 : case GI_IR_NODE_CONSTANT:
545 : 0 : size = sizeof (ConstantBlob);
546 : 0 : break;
547 : :
548 : 0 : case GI_IR_NODE_XREF:
549 : 0 : size = 0;
550 : 0 : break;
551 : :
552 : 0 : case GI_IR_NODE_UNION:
553 : : {
554 : 0 : GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
555 : :
556 : 0 : size = sizeof (UnionBlob);
557 [ # # ]: 0 : for (l = union_->members; l; l = l->next)
558 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
559 [ # # ]: 0 : for (l = union_->discriminators; l; l = l->next)
560 : 0 : size += gi_ir_node_get_size ((GIIrNode *)l->data);
561 : : }
562 : 0 : break;
563 : :
564 : 0 : default:
565 : 0 : g_error ("Unhandled node type '%s'", gi_ir_node_type_to_string (node->type));
566 : : size = 0;
567 : : }
568 : :
569 : 0 : g_debug ("node %p type '%s' size %zu", node,
570 : : gi_ir_node_type_to_string (node->type), size);
571 : :
572 : 0 : g_assert (size <= G_MAXUINT32);
573 : :
574 : 0 : return (guint32) size;
575 : : }
576 : :
577 : : static void
578 : 0 : add_attribute_size (gpointer key, gpointer value, gpointer data)
579 : : {
580 : 0 : const char *key_str = key;
581 : 0 : const char *value_str = value;
582 : 0 : size_t *size_p = data;
583 : :
584 : 0 : *size_p += sizeof (AttributeBlob);
585 : 0 : *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
586 : 0 : *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
587 : 0 : }
588 : :
589 : : /* returns the full size of the blob including variable-size parts (including attributes) */
590 : : static uint32_t
591 : 0 : gi_ir_node_get_full_size_internal (GIIrNode *parent,
592 : : GIIrNode *node)
593 : : {
594 : : GList *l;
595 : : size_t size, n;
596 : :
597 : 0 : g_assert (node != NULL);
598 : :
599 : 0 : g_debug ("node %p type '%s'", node,
600 : : gi_ir_node_type_to_string (node->type));
601 : :
602 [ # # # # : 0 : switch (node->type)
# # # # #
# # # # #
# # # # ]
603 : : {
604 : 0 : case GI_IR_NODE_CALLBACK:
605 : : {
606 : 0 : GIIrNodeFunction *function = (GIIrNodeFunction *)node;
607 : 0 : size = sizeof (CallbackBlob);
608 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
609 [ # # ]: 0 : for (l = function->parameters; l; l = l->next)
610 : : {
611 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
612 : : }
613 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)function->result);
614 : : }
615 : 0 : break;
616 : :
617 : 0 : case GI_IR_NODE_FUNCTION:
618 : : {
619 : 0 : GIIrNodeFunction *function = (GIIrNodeFunction *)node;
620 : 0 : size = sizeof (FunctionBlob);
621 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
622 : 0 : size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
623 [ # # ]: 0 : for (l = function->parameters; l; l = l->next)
624 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
625 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)function->result);
626 : : }
627 : 0 : break;
628 : :
629 : 0 : case GI_IR_NODE_PARAM:
630 : : {
631 : 0 : GIIrNodeParam *param = (GIIrNodeParam *)node;
632 : :
633 : : /* See the comment in the GI_IR_NODE_PARAM/ArgBlob writing below */
634 : 0 : size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
635 [ # # ]: 0 : if (node->name)
636 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
637 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)param->type);
638 : : }
639 : 0 : break;
640 : :
641 : 0 : case GI_IR_NODE_TYPE:
642 : : {
643 : 0 : GIIrNodeType *type = (GIIrNodeType *)node;
644 : 0 : size = sizeof (SimpleTypeBlob);
645 [ # # # # ]: 0 : if (!GI_TYPE_TAG_IS_BASIC (type->tag))
646 : : {
647 : 0 : g_debug ("node %p type tag '%s'", node,
648 : : gi_type_tag_to_string (type->tag));
649 : :
650 [ # # # # : 0 : switch (type->tag)
# # ]
651 : : {
652 : 0 : case GI_TYPE_TAG_ARRAY:
653 : 0 : size = sizeof (ArrayTypeBlob);
654 [ # # ]: 0 : if (type->parameter_type1)
655 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
656 : 0 : break;
657 : 0 : case GI_TYPE_TAG_INTERFACE:
658 : 0 : size += sizeof (InterfaceTypeBlob);
659 : 0 : break;
660 : 0 : case GI_TYPE_TAG_GLIST:
661 : : case GI_TYPE_TAG_GSLIST:
662 : 0 : size += sizeof (ParamTypeBlob);
663 [ # # ]: 0 : if (type->parameter_type1)
664 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
665 : 0 : break;
666 : 0 : case GI_TYPE_TAG_GHASH:
667 : 0 : size += sizeof (ParamTypeBlob) * 2;
668 [ # # ]: 0 : if (type->parameter_type1)
669 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
670 [ # # ]: 0 : if (type->parameter_type2)
671 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type2);
672 : 0 : break;
673 : 0 : case GI_TYPE_TAG_ERROR:
674 : 0 : size += sizeof (ErrorTypeBlob);
675 : 0 : break;
676 : 0 : default:
677 : 0 : g_error ("Unknown type tag %d", type->tag);
678 : : break;
679 : : }
680 : : }
681 : : }
682 : 0 : break;
683 : :
684 : 0 : case GI_IR_NODE_OBJECT:
685 : : {
686 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
687 : :
688 : 0 : n = g_list_length (iface->interfaces);
689 : 0 : size = sizeof(ObjectBlob);
690 [ # # ]: 0 : if (iface->parent)
691 : 0 : size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
692 [ # # ]: 0 : if (iface->glib_type_struct)
693 : 0 : size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
694 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
695 : 0 : size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
696 [ # # ]: 0 : if (iface->gtype_init)
697 : 0 : size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
698 [ # # ]: 0 : if (iface->ref_func)
699 : 0 : size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4);
700 [ # # ]: 0 : if (iface->unref_func)
701 : 0 : size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4);
702 [ # # ]: 0 : if (iface->set_value_func)
703 : 0 : size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4);
704 [ # # ]: 0 : if (iface->get_value_func)
705 : 0 : size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4);
706 : 0 : size += 2 * (n + (n % 2));
707 : :
708 [ # # ]: 0 : for (l = iface->members; l; l = l->next)
709 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
710 : : }
711 : 0 : break;
712 : :
713 : 0 : case GI_IR_NODE_INTERFACE:
714 : : {
715 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
716 : :
717 : 0 : n = g_list_length (iface->prerequisites);
718 : 0 : size = sizeof (InterfaceBlob);
719 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
720 : 0 : size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
721 : 0 : size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
722 : 0 : size += 2 * (n + (n % 2));
723 : :
724 [ # # ]: 0 : for (l = iface->members; l; l = l->next)
725 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
726 : : }
727 : 0 : break;
728 : :
729 : 0 : case GI_IR_NODE_ENUM:
730 : : case GI_IR_NODE_FLAGS:
731 : : {
732 : 0 : GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
733 : :
734 : 0 : size = sizeof (EnumBlob);
735 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
736 [ # # ]: 0 : if (enum_->gtype_name)
737 : : {
738 : 0 : size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
739 : 0 : size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
740 : : }
741 [ # # ]: 0 : if (enum_->error_domain)
742 : 0 : size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4);
743 : :
744 [ # # ]: 0 : for (l = enum_->values; l; l = l->next)
745 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
746 [ # # ]: 0 : for (l = enum_->methods; l; l = l->next)
747 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
748 : : }
749 : 0 : break;
750 : :
751 : 0 : case GI_IR_NODE_VALUE:
752 : : {
753 : 0 : size = sizeof (ValueBlob);
754 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
755 : : }
756 : 0 : break;
757 : :
758 : 0 : case GI_IR_NODE_STRUCT:
759 : : {
760 : 0 : GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
761 : :
762 : 0 : size = sizeof (StructBlob);
763 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
764 [ # # ]: 0 : if (struct_->gtype_name)
765 : 0 : size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
766 [ # # ]: 0 : if (struct_->gtype_init)
767 : 0 : size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
768 [ # # ]: 0 : if (struct_->copy_func)
769 : 0 : size += ALIGN_VALUE (strlen (struct_->copy_func) + 1, 4);
770 [ # # ]: 0 : if (struct_->free_func)
771 : 0 : size += ALIGN_VALUE (strlen (struct_->free_func) + 1, 4);
772 [ # # ]: 0 : for (l = struct_->members; l; l = l->next)
773 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
774 : : }
775 : 0 : break;
776 : :
777 : 0 : case GI_IR_NODE_BOXED:
778 : : {
779 : 0 : GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
780 : :
781 : 0 : size = sizeof (StructBlob);
782 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
783 [ # # ]: 0 : if (boxed->gtype_name)
784 : : {
785 : 0 : size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
786 : 0 : size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
787 : : }
788 [ # # ]: 0 : for (l = boxed->members; l; l = l->next)
789 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
790 : : }
791 : 0 : break;
792 : :
793 : 0 : case GI_IR_NODE_PROPERTY:
794 : : {
795 : 0 : GIIrNodeProperty *prop = (GIIrNodeProperty *)node;
796 : :
797 : 0 : size = sizeof (PropertyBlob);
798 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
799 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)prop->type);
800 : : }
801 : 0 : break;
802 : :
803 : 0 : case GI_IR_NODE_SIGNAL:
804 : : {
805 : 0 : GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
806 : :
807 : 0 : size = sizeof (SignalBlob);
808 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
809 [ # # ]: 0 : for (l = signal->parameters; l; l = l->next)
810 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
811 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)signal->result);
812 : : }
813 : 0 : break;
814 : :
815 : 0 : case GI_IR_NODE_VFUNC:
816 : : {
817 : 0 : GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
818 : :
819 : 0 : size = sizeof (VFuncBlob);
820 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
821 [ # # ]: 0 : for (l = vfunc->parameters; l; l = l->next)
822 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
823 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)vfunc->result);
824 : : }
825 : 0 : break;
826 : :
827 : 0 : case GI_IR_NODE_FIELD:
828 : : {
829 : 0 : GIIrNodeField *field = (GIIrNodeField *)node;
830 : :
831 : 0 : size = sizeof (FieldBlob);
832 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
833 [ # # ]: 0 : if (field->callback)
834 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)field->callback);
835 : : else
836 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)field->type);
837 : : }
838 : 0 : break;
839 : :
840 : 0 : case GI_IR_NODE_CONSTANT:
841 : : {
842 : 0 : GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
843 : :
844 : 0 : size = sizeof (ConstantBlob);
845 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
846 : : /* FIXME non-string values */
847 : 0 : size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
848 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)constant->type);
849 : : }
850 : 0 : break;
851 : :
852 : 0 : case GI_IR_NODE_XREF:
853 : : {
854 : 0 : GIIrNodeXRef *xref = (GIIrNodeXRef *)node;
855 : :
856 : 0 : size = 0;
857 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
858 : 0 : size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
859 : : }
860 : 0 : break;
861 : :
862 : 0 : case GI_IR_NODE_UNION:
863 : : {
864 : 0 : GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
865 : :
866 : 0 : size = sizeof (UnionBlob);
867 : 0 : size += ALIGN_VALUE (strlen (node->name) + 1, 4);
868 [ # # ]: 0 : if (union_->gtype_name)
869 : 0 : size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
870 [ # # ]: 0 : if (union_->gtype_init)
871 : 0 : size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
872 [ # # ]: 0 : if (union_->copy_func)
873 : 0 : size += ALIGN_VALUE (strlen (union_->copy_func) + 1, 4);
874 [ # # ]: 0 : if (union_->free_func)
875 : 0 : size += ALIGN_VALUE (strlen (union_->free_func) + 1, 4);
876 [ # # ]: 0 : for (l = union_->members; l; l = l->next)
877 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
878 [ # # ]: 0 : for (l = union_->discriminators; l; l = l->next)
879 : 0 : size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
880 : : }
881 : 0 : break;
882 : :
883 : 0 : default:
884 : 0 : g_error ("Unknown type tag %d", node->type);
885 : : size = 0;
886 : : }
887 : :
888 [ # # # # : 0 : g_debug ("node %s%s%s%p type '%s' full size %zu",
# # ]
889 : : node->name ? "'" : "",
890 : : node->name ? node->name : "",
891 : : node->name ? "' " : "",
892 : : node, gi_ir_node_type_to_string (node->type), size);
893 : :
894 : 0 : g_hash_table_foreach (node->attributes, add_attribute_size, &size);
895 : :
896 : 0 : g_assert (size <= G_MAXUINT32);
897 : :
898 : 0 : return size;
899 : : }
900 : :
901 : : uint32_t
902 : 0 : gi_ir_node_get_full_size (GIIrNode *node)
903 : : {
904 : 0 : return gi_ir_node_get_full_size_internal (NULL, node);
905 : : }
906 : :
907 : : int
908 : 0 : gi_ir_node_cmp (GIIrNode *node,
909 : : GIIrNode *other)
910 : : {
911 [ # # ]: 0 : if (node->type < other->type)
912 : 0 : return -1;
913 [ # # ]: 0 : else if (node->type > other->type)
914 : 0 : return 1;
915 : : else
916 : 0 : return strcmp (node->name, other->name);
917 : : }
918 : :
919 : : gboolean
920 : 0 : gi_ir_node_can_have_member (GIIrNode *node)
921 : : {
922 [ # # # ]: 0 : switch (node->type)
923 : : {
924 : 0 : case GI_IR_NODE_OBJECT:
925 : : case GI_IR_NODE_INTERFACE:
926 : : case GI_IR_NODE_BOXED:
927 : : case GI_IR_NODE_STRUCT:
928 : : case GI_IR_NODE_UNION:
929 : 0 : return TRUE;
930 : : /* list others individually rather than with default: so that compiler
931 : : * warns if new node types are added without adding them to the switch
932 : : */
933 : 0 : case GI_IR_NODE_INVALID:
934 : : case GI_IR_NODE_FUNCTION:
935 : : case GI_IR_NODE_CALLBACK:
936 : : case GI_IR_NODE_ENUM:
937 : : case GI_IR_NODE_FLAGS:
938 : : case GI_IR_NODE_CONSTANT:
939 : : case GI_IR_NODE_INVALID_0:
940 : : case GI_IR_NODE_PARAM:
941 : : case GI_IR_NODE_TYPE:
942 : : case GI_IR_NODE_PROPERTY:
943 : : case GI_IR_NODE_SIGNAL:
944 : : case GI_IR_NODE_VALUE:
945 : : case GI_IR_NODE_VFUNC:
946 : : case GI_IR_NODE_FIELD:
947 : : case GI_IR_NODE_XREF:
948 : 0 : return FALSE;
949 : 0 : default:
950 : : g_assert_not_reached ();
951 : : };
952 : : return FALSE;
953 : : }
954 : :
955 : : void
956 : 0 : gi_ir_node_add_member (GIIrNode *node,
957 : : GIIrNodeFunction *member)
958 : : {
959 : 0 : g_return_if_fail (node != NULL);
960 : 0 : g_return_if_fail (member != NULL);
961 : :
962 [ # # # # : 0 : switch (node->type)
# ]
963 : : {
964 : 0 : case GI_IR_NODE_OBJECT:
965 : : case GI_IR_NODE_INTERFACE:
966 : : {
967 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
968 : 0 : iface->members =
969 : 0 : g_list_insert_sorted (iface->members, member,
970 : : (GCompareFunc) gi_ir_node_cmp);
971 : 0 : break;
972 : : }
973 : 0 : case GI_IR_NODE_BOXED:
974 : : {
975 : 0 : GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
976 : 0 : boxed->members =
977 : 0 : g_list_insert_sorted (boxed->members, member,
978 : : (GCompareFunc) gi_ir_node_cmp);
979 : 0 : break;
980 : : }
981 : 0 : case GI_IR_NODE_STRUCT:
982 : : {
983 : 0 : GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
984 : 0 : struct_->members =
985 : 0 : g_list_insert_sorted (struct_->members, member,
986 : : (GCompareFunc) gi_ir_node_cmp);
987 : 0 : break;
988 : : }
989 : 0 : case GI_IR_NODE_UNION:
990 : : {
991 : 0 : GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
992 : 0 : union_->members =
993 : 0 : g_list_insert_sorted (union_->members, member,
994 : : (GCompareFunc) gi_ir_node_cmp);
995 : 0 : break;
996 : : }
997 : 0 : default:
998 : 0 : g_error ("Cannot add a member to unknown type tag type %d",
999 : : node->type);
1000 : : break;
1001 : : }
1002 : : }
1003 : :
1004 : : const char *
1005 : 0 : gi_ir_node_param_direction_string (GIIrNodeParam * node)
1006 : : {
1007 [ # # ]: 0 : if (node->out)
1008 : : {
1009 [ # # ]: 0 : if (node->in)
1010 : 0 : return "in-out";
1011 : : else
1012 : 0 : return "out";
1013 : : }
1014 : 0 : return "in";
1015 : : }
1016 : :
1017 : : static int64_t
1018 : 0 : parse_int_value (const char *str)
1019 : : {
1020 : 0 : return g_ascii_strtoll (str, NULL, 0);
1021 : : }
1022 : :
1023 : : static uint64_t
1024 : 0 : parse_uint_value (const char *str)
1025 : : {
1026 : 0 : return g_ascii_strtoull (str, NULL, 0);
1027 : : }
1028 : :
1029 : : static double
1030 : 0 : parse_float_value (const char *str)
1031 : : {
1032 : 0 : return g_ascii_strtod (str, NULL);
1033 : : }
1034 : :
1035 : : static gboolean
1036 : 0 : parse_boolean_value (const char *str)
1037 : : {
1038 [ # # ]: 0 : if (g_ascii_strcasecmp (str, "TRUE") == 0)
1039 : 0 : return TRUE;
1040 : :
1041 [ # # ]: 0 : if (g_ascii_strcasecmp (str, "FALSE") == 0)
1042 : 0 : return FALSE;
1043 : :
1044 : 0 : return parse_int_value (str) ? TRUE : FALSE;
1045 : : }
1046 : :
1047 : : static GIIrNode *
1048 : 0 : find_entry_node (GIIrTypelibBuild *build,
1049 : : const char *name,
1050 : : uint16_t *idx)
1051 : :
1052 : : {
1053 : 0 : GIIrModule *module = build->module;
1054 : : GList *l;
1055 : : size_t i;
1056 : : unsigned int n_names;
1057 : : char **names;
1058 : 0 : GIIrNode *result = NULL;
1059 : :
1060 : 0 : g_assert (name != NULL);
1061 : 0 : g_assert (strlen (name) > 0);
1062 : :
1063 : 0 : names = g_strsplit (name, ".", 0);
1064 : 0 : n_names = g_strv_length (names);
1065 [ # # ]: 0 : if (n_names > 2)
1066 : 0 : g_error ("Too many name parts");
1067 : :
1068 [ # # ]: 0 : for (l = module->entries, i = 1; l; l = l->next, i++)
1069 : : {
1070 : 0 : GIIrNode *node = (GIIrNode *)l->data;
1071 : :
1072 [ # # ]: 0 : if (n_names > 1)
1073 : : {
1074 [ # # ]: 0 : if (node->type != GI_IR_NODE_XREF)
1075 : 0 : continue;
1076 : :
1077 [ # # ]: 0 : if (((GIIrNodeXRef *)node)->namespace == NULL ||
1078 [ # # ]: 0 : strcmp (((GIIrNodeXRef *)node)->namespace, names[0]) != 0)
1079 : 0 : continue;
1080 : : }
1081 : :
1082 [ # # ]: 0 : if (strcmp (node->name, names[n_names - 1]) == 0)
1083 : : {
1084 [ # # ]: 0 : if (idx)
1085 : 0 : *idx = i;
1086 : :
1087 : 0 : result = node;
1088 : 0 : goto out;
1089 : : }
1090 : : }
1091 : :
1092 [ # # ]: 0 : if (n_names > 1)
1093 : : {
1094 : 0 : GIIrNode *node = gi_ir_node_new (GI_IR_NODE_XREF, module);
1095 : :
1096 : 0 : ((GIIrNodeXRef *)node)->namespace = g_strdup (names[0]);
1097 : 0 : node->name = g_strdup (names[1]);
1098 : :
1099 : 0 : module->entries = g_list_append (module->entries, node);
1100 : :
1101 [ # # ]: 0 : if (idx)
1102 : 0 : *idx = g_list_length (module->entries);
1103 : :
1104 : 0 : result = node;
1105 : :
1106 : 0 : g_debug ("Creating XREF: %s %s", names[0], names[1]);
1107 : :
1108 : 0 : goto out;
1109 : : }
1110 : :
1111 : :
1112 : 0 : gi_ir_module_fatal (build, 0, "type reference '%s' not found", name);
1113 : 0 : out:
1114 : :
1115 : 0 : g_strfreev (names);
1116 : :
1117 : 0 : return result;
1118 : : }
1119 : :
1120 : : static uint16_t
1121 : 0 : find_entry (GIIrTypelibBuild *build,
1122 : : const char *name)
1123 : : {
1124 : 0 : uint16_t idx = 0;
1125 : :
1126 : 0 : find_entry_node (build, name, &idx);
1127 : :
1128 : 0 : return idx;
1129 : : }
1130 : :
1131 : : static GIIrModule *
1132 : 0 : find_namespace (GIIrModule *module,
1133 : : const char *name)
1134 : : {
1135 : : GIIrModule *target;
1136 : : GList *l;
1137 : :
1138 [ # # ]: 0 : if (strcmp (module->name, name) == 0)
1139 : 0 : return module;
1140 : :
1141 [ # # ]: 0 : for (l = module->include_modules; l; l = l->next)
1142 : : {
1143 : 0 : GIIrModule *submodule = l->data;
1144 : :
1145 [ # # ]: 0 : if (strcmp (submodule->name, name) == 0)
1146 : 0 : return submodule;
1147 : :
1148 : 0 : target = find_namespace (submodule, name);
1149 [ # # ]: 0 : if (target)
1150 : 0 : return target;
1151 : : }
1152 : 0 : return NULL;
1153 : : }
1154 : :
1155 : : GIIrNode *
1156 : 0 : gi_ir_find_node (GIIrTypelibBuild *build,
1157 : : GIIrModule *src_module,
1158 : : const char *name)
1159 : : {
1160 : : GList *l;
1161 : 0 : GIIrNode *return_node = NULL;
1162 : 0 : char **names = g_strsplit (name, ".", 0);
1163 : 0 : unsigned n_names = g_strv_length (names);
1164 : : const char *target_name;
1165 : : GIIrModule *target_module;
1166 : :
1167 [ # # ]: 0 : if (n_names == 1)
1168 : : {
1169 : 0 : target_module = src_module;
1170 : 0 : target_name = name;
1171 : : }
1172 : : else
1173 : : {
1174 : 0 : target_module = find_namespace (build->module, names[0]);
1175 : 0 : target_name = names[1];
1176 : : }
1177 : :
1178 : : /* find_namespace() may return NULL. */
1179 [ # # ]: 0 : if (target_module == NULL)
1180 : 0 : goto done;
1181 : :
1182 [ # # ]: 0 : for (l = target_module->entries; l; l = l->next)
1183 : : {
1184 : 0 : GIIrNode *node = (GIIrNode *)l->data;
1185 : :
1186 [ # # ]: 0 : if (strcmp (node->name, target_name) == 0)
1187 : : {
1188 : 0 : return_node = node;
1189 : 0 : break;
1190 : : }
1191 : : }
1192 : :
1193 : 0 : done:
1194 : 0 : g_strfreev (names);
1195 : :
1196 : 0 : return return_node;
1197 : : }
1198 : :
1199 : : static int
1200 : 0 : get_index_of_member_type (GIIrNodeInterface *node,
1201 : : GIIrNodeTypeId type,
1202 : : const char *name)
1203 : : {
1204 : 0 : int index = -1;
1205 : : GList *l;
1206 : :
1207 [ # # ]: 0 : for (l = node->members; l; l = l->next)
1208 : : {
1209 : 0 : GIIrNode *member_node = l->data;
1210 : :
1211 [ # # ]: 0 : if (member_node->type != type)
1212 : 0 : continue;
1213 : :
1214 : 0 : index++;
1215 : :
1216 [ # # ]: 0 : if (strcmp (member_node->name, name) == 0)
1217 : 0 : break;
1218 : : }
1219 : :
1220 : 0 : return index;
1221 : : }
1222 : :
1223 : : static void
1224 : 0 : serialize_type (GIIrTypelibBuild *build,
1225 : : GIIrNodeType *node,
1226 : : GString *str)
1227 : : {
1228 : : size_t i;
1229 : :
1230 [ # # # # ]: 0 : if (GI_TYPE_TAG_IS_BASIC (node->tag))
1231 : : {
1232 : 0 : g_string_append_printf (str, "%s%s", gi_type_tag_to_string (node->tag),
1233 [ # # ]: 0 : node->is_pointer ? "*" : "");
1234 : : }
1235 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_ARRAY)
1236 : : {
1237 [ # # ]: 0 : if (node->array_type == GI_ARRAY_TYPE_C)
1238 : : {
1239 : 0 : serialize_type (build, node->parameter_type1, str);
1240 [ # # ]: 0 : g_string_append (str, "[");
1241 : :
1242 [ # # ]: 0 : if (node->has_length)
1243 : 0 : g_string_append_printf (str, "length=%d", node->length);
1244 [ # # ]: 0 : else if (node->has_size)
1245 : 0 : g_string_append_printf (str, "fixed-size=%" G_GSIZE_FORMAT, node->size);
1246 : :
1247 [ # # ]: 0 : if (node->zero_terminated)
1248 : 0 : g_string_append_printf (str, "%szero-terminated=1",
1249 [ # # ]: 0 : node->has_length ? "," : "");
1250 : :
1251 [ # # ]: 0 : g_string_append (str, "]");
1252 [ # # ]: 0 : if (node->is_pointer)
1253 [ # # ]: 0 : g_string_append (str, "*");
1254 : : }
1255 [ # # ]: 0 : else if (node->array_type == GI_ARRAY_TYPE_BYTE_ARRAY)
1256 : : {
1257 : : /* We on purpose skip serializing parameter_type1, which should
1258 : : always be void*
1259 : : */
1260 [ # # ]: 0 : g_string_append (str, "GByteArray");
1261 : : }
1262 : : else
1263 : : {
1264 [ # # ]: 0 : if (node->array_type == GI_ARRAY_TYPE_ARRAY)
1265 [ # # ]: 0 : g_string_append (str, "GArray");
1266 : : else
1267 [ # # ]: 0 : g_string_append (str, "GPtrArray");
1268 [ # # ]: 0 : if (node->parameter_type1)
1269 : : {
1270 [ # # ]: 0 : g_string_append (str, "<");
1271 : 0 : serialize_type (build, node->parameter_type1, str);
1272 [ # # ]: 0 : g_string_append (str, ">");
1273 : : }
1274 : : }
1275 : : }
1276 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_INTERFACE)
1277 : : {
1278 : : GIIrNode *iface;
1279 : : char *name;
1280 : :
1281 : 0 : iface = find_entry_node (build, node->giinterface, NULL);
1282 [ # # ]: 0 : if (iface)
1283 : : {
1284 [ # # ]: 0 : if (iface->type == GI_IR_NODE_XREF)
1285 : 0 : g_string_append_printf (str, "%s.", ((GIIrNodeXRef *)iface)->namespace);
1286 : 0 : name = iface->name;
1287 : : }
1288 : : else
1289 : : {
1290 : 0 : g_warning ("Interface for type reference %s not found", node->giinterface);
1291 : 0 : name = node->giinterface;
1292 : : }
1293 : :
1294 : 0 : g_string_append_printf (str, "%s%s", name,
1295 [ # # ]: 0 : node->is_pointer ? "*" : "");
1296 : : }
1297 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_GLIST)
1298 : : {
1299 [ # # ]: 0 : g_string_append (str, "GList");
1300 [ # # ]: 0 : if (node->parameter_type1)
1301 : : {
1302 [ # # ]: 0 : g_string_append (str, "<");
1303 : 0 : serialize_type (build, node->parameter_type1, str);
1304 [ # # ]: 0 : g_string_append (str, ">");
1305 : : }
1306 : : }
1307 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_GSLIST)
1308 : : {
1309 [ # # ]: 0 : g_string_append (str, "GSList");
1310 [ # # ]: 0 : if (node->parameter_type1)
1311 : : {
1312 [ # # ]: 0 : g_string_append (str, "<");
1313 : 0 : serialize_type (build, node->parameter_type1, str);
1314 [ # # ]: 0 : g_string_append (str, ">");
1315 : : }
1316 : : }
1317 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_GHASH)
1318 : : {
1319 [ # # ]: 0 : g_string_append (str, "GHashTable");
1320 [ # # ]: 0 : if (node->parameter_type1)
1321 : : {
1322 [ # # ]: 0 : g_string_append (str, "<");
1323 : 0 : serialize_type (build, node->parameter_type1, str);
1324 [ # # ]: 0 : g_string_append (str, ",");
1325 : 0 : serialize_type (build, node->parameter_type2, str);
1326 [ # # ]: 0 : g_string_append (str, ">");
1327 : : }
1328 : : }
1329 [ # # ]: 0 : else if (node->tag == GI_TYPE_TAG_ERROR)
1330 : : {
1331 [ # # ]: 0 : g_string_append (str, "GError");
1332 [ # # ]: 0 : if (node->errors)
1333 : : {
1334 [ # # ]: 0 : g_string_append (str, "<");
1335 [ # # ]: 0 : for (i = 0; node->errors[i]; i++)
1336 : : {
1337 [ # # ]: 0 : if (i > 0)
1338 [ # # ]: 0 : g_string_append (str, ",");
1339 [ # # ]: 0 : g_string_append (str, node->errors[i]);
1340 : : }
1341 [ # # ]: 0 : g_string_append (str, ">");
1342 : : }
1343 : : }
1344 : 0 : }
1345 : :
1346 : : static void
1347 : 0 : gi_ir_node_build_members (GList **members,
1348 : : GIIrNodeTypeId type,
1349 : : uint16_t *count,
1350 : : GIIrNode *parent,
1351 : : GIIrTypelibBuild *build,
1352 : : uint32_t *offset,
1353 : : uint32_t *offset2,
1354 : : uint16_t *count2)
1355 : : {
1356 : 0 : GList *l = *members;
1357 : :
1358 [ # # ]: 0 : while (l)
1359 : : {
1360 : 0 : GIIrNode *member = (GIIrNode *)l->data;
1361 : 0 : GList *next = l->next;
1362 : :
1363 [ # # ]: 0 : if (member->type == type)
1364 : : {
1365 : 0 : (*count)++;
1366 : 0 : gi_ir_node_build_typelib (member, parent, build, offset, offset2, count2);
1367 : 0 : *members = g_list_delete_link (*members, l);
1368 : : }
1369 : 0 : l = next;
1370 : : }
1371 : 0 : }
1372 : :
1373 : : static void
1374 : 0 : gi_ir_node_check_unhandled_members (GList **members,
1375 : : GIIrNodeTypeId container_type)
1376 : : {
1377 : : #if 0
1378 : : if (*members)
1379 : : {
1380 : : GList *l;
1381 : :
1382 : : for (l = *members; l; l = l->next)
1383 : : {
1384 : : GIIrNode *member = (GIIrNode *)l->data;
1385 : : g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
1386 : : gi_ir_node_type_to_string (container_type),
1387 : : member->name,
1388 : : gi_ir_node_type_to_string (member->type));
1389 : : }
1390 : :
1391 : : g_list_free (*members);
1392 : : *members = NULL;
1393 : :
1394 : : g_error ("Unhandled members. Aborting.");
1395 : : }
1396 : : #else
1397 : 0 : g_list_free (*members);
1398 : 0 : *members = NULL;
1399 : : #endif
1400 : 0 : }
1401 : :
1402 : : void
1403 : 0 : gi_ir_node_build_typelib (GIIrNode *node,
1404 : : GIIrNode *parent,
1405 : : GIIrTypelibBuild *build,
1406 : : uint32_t *offset,
1407 : : uint32_t *offset2,
1408 : : uint16_t *count2)
1409 : : {
1410 : : gboolean appended_stack;
1411 : 0 : GHashTable *strings = build->strings;
1412 : 0 : GHashTable *types = build->types;
1413 : 0 : uint8_t *data = build->data;
1414 : : GList *l;
1415 : 0 : uint32_t old_offset = *offset;
1416 : 0 : uint32_t old_offset2 = *offset2;
1417 : :
1418 : 0 : g_assert (node != NULL);
1419 : :
1420 [ # # # # ]: 0 : g_debug ("build_typelib: %s%s(%s)",
1421 : : node->name ? node->name : "",
1422 : : node->name ? " " : "",
1423 : : gi_ir_node_type_to_string (node->type));
1424 : :
1425 [ # # ]: 0 : if (build->stack)
1426 : 0 : appended_stack = node != (GIIrNode*)build->stack->data;
1427 : : else
1428 : 0 : appended_stack = TRUE;
1429 [ # # ]: 0 : if (appended_stack)
1430 : 0 : build->stack = g_list_prepend (build->stack, node);
1431 : :
1432 : 0 : gi_ir_node_compute_offsets (build, node);
1433 : :
1434 : : /* We should only be building each node once. If we do a typelib expansion, we also
1435 : : * reset the offset in girmodule.c.
1436 : : */
1437 : 0 : g_assert (node->offset == 0);
1438 : 0 : node->offset = *offset;
1439 : 0 : build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, node);
1440 : :
1441 : 0 : build->n_attributes += g_hash_table_size (node->attributes);
1442 : :
1443 [ # # # # : 0 : switch (node->type)
# # # # #
# # # # #
# # # ]
1444 : : {
1445 : 0 : case GI_IR_NODE_TYPE:
1446 : : {
1447 : 0 : GIIrNodeType *type = (GIIrNodeType *)node;
1448 : 0 : SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1449 : :
1450 : 0 : *offset += sizeof (SimpleTypeBlob);
1451 : :
1452 [ # # # # ]: 0 : if (GI_TYPE_TAG_IS_BASIC (type->tag))
1453 : : {
1454 : 0 : blob->flags.reserved = 0;
1455 : 0 : blob->flags.reserved2 = 0;
1456 : 0 : blob->flags.pointer = type->is_pointer;
1457 : 0 : blob->flags.reserved3 = 0;
1458 : 0 : blob->flags.tag = type->tag;
1459 : : }
1460 : : else
1461 : : {
1462 : : GString *str;
1463 : : char *s;
1464 : : gpointer value;
1465 : :
1466 : 0 : str = g_string_new (0);
1467 : 0 : serialize_type (build, type, str);
1468 : 0 : s = g_string_free (str, FALSE);
1469 : :
1470 : 0 : types_count += 1;
1471 : 0 : value = g_hash_table_lookup (types, s);
1472 [ # # ]: 0 : if (value)
1473 : : {
1474 : 0 : blob->offset = GPOINTER_TO_UINT (value);
1475 : 0 : g_free (s);
1476 : : }
1477 : : else
1478 : : {
1479 : 0 : unique_types_count += 1;
1480 : 0 : g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2));
1481 : :
1482 : 0 : blob->offset = *offset2;
1483 [ # # # # : 0 : switch (type->tag)
# # ]
1484 : : {
1485 : 0 : case GI_TYPE_TAG_ARRAY:
1486 : : {
1487 : 0 : ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1488 : : uint32_t pos;
1489 : :
1490 : 0 : array->pointer = type->is_pointer;
1491 : 0 : array->reserved = 0;
1492 : 0 : array->tag = type->tag;
1493 : 0 : array->zero_terminated = type->zero_terminated;
1494 : 0 : array->has_length = type->has_length;
1495 : 0 : array->has_size = type->has_size;
1496 : 0 : array->array_type = type->array_type;
1497 : 0 : array->reserved2 = 0;
1498 [ # # ]: 0 : if (array->has_length)
1499 : 0 : array->dimensions.length = type->length;
1500 [ # # ]: 0 : else if (array->has_size)
1501 : 0 : array->dimensions.size = type->size;
1502 : : else
1503 : 0 : array->dimensions.length = -1;
1504 : :
1505 : 0 : pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
1506 : 0 : *offset2 += sizeof (ArrayTypeBlob);
1507 : :
1508 : 0 : gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
1509 : : node, build, &pos, offset2, NULL);
1510 : : }
1511 : 0 : break;
1512 : :
1513 : 0 : case GI_TYPE_TAG_INTERFACE:
1514 : : {
1515 : 0 : InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1516 : 0 : *offset2 += sizeof (InterfaceTypeBlob);
1517 : :
1518 : 0 : iface->pointer = type->is_pointer;
1519 : 0 : iface->reserved = 0;
1520 : 0 : iface->tag = type->tag;
1521 : 0 : iface->reserved2 = 0;
1522 : 0 : iface->interface = find_entry (build, type->giinterface);
1523 : :
1524 : : }
1525 : 0 : break;
1526 : :
1527 : 0 : case GI_TYPE_TAG_GLIST:
1528 : : case GI_TYPE_TAG_GSLIST:
1529 : : {
1530 : 0 : ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1531 : : uint32_t pos;
1532 : :
1533 : 0 : param->pointer = 1;
1534 : 0 : param->reserved = 0;
1535 : 0 : param->tag = type->tag;
1536 : 0 : param->reserved2 = 0;
1537 : 0 : param->n_types = 1;
1538 : :
1539 : 0 : pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1540 : 0 : *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
1541 : :
1542 : 0 : gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
1543 : : node, build, &pos, offset2, NULL);
1544 : : }
1545 : 0 : break;
1546 : :
1547 : 0 : case GI_TYPE_TAG_GHASH:
1548 : : {
1549 : 0 : ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1550 : : uint32_t pos;
1551 : :
1552 : 0 : param->pointer = 1;
1553 : 0 : param->reserved = 0;
1554 : 0 : param->tag = type->tag;
1555 : 0 : param->reserved2 = 0;
1556 : 0 : param->n_types = 2;
1557 : :
1558 : 0 : pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1559 : 0 : *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
1560 : :
1561 : 0 : gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
1562 : : node, build, &pos, offset2, NULL);
1563 : 0 : gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type2,
1564 : : node, build, &pos, offset2, NULL);
1565 : : }
1566 : 0 : break;
1567 : :
1568 : 0 : case GI_TYPE_TAG_ERROR:
1569 : : {
1570 : 0 : ErrorTypeBlob *error_blob = (ErrorTypeBlob *)&data[*offset2];
1571 : :
1572 : 0 : error_blob->pointer = 1;
1573 : 0 : error_blob->reserved = 0;
1574 : 0 : error_blob->tag = type->tag;
1575 : 0 : error_blob->reserved2 = 0;
1576 : 0 : error_blob->n_domains = 0;
1577 : :
1578 : 0 : *offset2 += sizeof (ErrorTypeBlob);
1579 : : }
1580 : 0 : break;
1581 : :
1582 : 0 : default:
1583 : 0 : g_error ("Unknown type tag %d", type->tag);
1584 : : break;
1585 : : }
1586 : : }
1587 : : }
1588 : : }
1589 : 0 : break;
1590 : :
1591 : 0 : case GI_IR_NODE_FIELD:
1592 : : {
1593 : 0 : GIIrNodeField *field = (GIIrNodeField *)node;
1594 : : FieldBlob *blob;
1595 : :
1596 : 0 : blob = (FieldBlob *)&data[*offset];
1597 : :
1598 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1599 : 0 : blob->readable = field->readable;
1600 : 0 : blob->writable = field->writable;
1601 : 0 : blob->reserved = 0;
1602 : 0 : blob->bits = 0;
1603 [ # # ]: 0 : if (field->offset_state == GI_IR_OFFSETS_COMPUTED)
1604 : 0 : blob->struct_offset = field->offset;
1605 : : else
1606 : 0 : blob->struct_offset = 0xFFFF; /* mark as unknown */
1607 : :
1608 [ # # ]: 0 : if (field->callback)
1609 : : {
1610 : 0 : blob->has_embedded_type = TRUE;
1611 : 0 : blob->type.offset = GI_INFO_TYPE_CALLBACK;
1612 : 0 : *offset += sizeof (FieldBlob);
1613 : 0 : gi_ir_node_build_typelib ((GIIrNode *)field->callback,
1614 : : node, build, offset, offset2, NULL);
1615 : : /* Fields with callbacks are bigger than normal, update count2
1616 : : * as an extra hint which represents the number of fields which are
1617 : : * callbacks. This allows us to gain constant time performance in the
1618 : : * repository for skipping over the fields section.
1619 : : */
1620 [ # # ]: 0 : if (count2)
1621 : 0 : (*count2)++;
1622 : : }
1623 : : else
1624 : : {
1625 : 0 : blob->has_embedded_type = FALSE;
1626 : : /* We handle the size member specially below, so subtract it */
1627 : 0 : *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
1628 : 0 : gi_ir_node_build_typelib ((GIIrNode *)field->type,
1629 : : node, build, offset, offset2, NULL);
1630 : : }
1631 : : }
1632 : 0 : break;
1633 : :
1634 : 0 : case GI_IR_NODE_PROPERTY:
1635 : : {
1636 : 0 : GIIrNodeProperty *prop = (GIIrNodeProperty *)node;
1637 : 0 : PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1638 : : /* We handle the size member specially below, so subtract it */
1639 : 0 : *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
1640 : :
1641 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1642 : 0 : blob->deprecated = prop->deprecated;
1643 : 0 : blob->readable = prop->readable;
1644 : 0 : blob->writable = prop->writable;
1645 : 0 : blob->construct = prop->construct;
1646 : 0 : blob->construct_only = prop->construct_only;
1647 : 0 : blob->transfer_ownership = prop->transfer;
1648 : 0 : blob->transfer_container_ownership = prop->shallow_transfer;
1649 : 0 : blob->reserved = 0;
1650 : :
1651 [ # # ]: 0 : if (prop->setter != NULL)
1652 : : {
1653 : 0 : int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
1654 : : GI_IR_NODE_FUNCTION,
1655 : 0 : prop->setter);
1656 [ # # ]: 0 : if (index == -1)
1657 : : {
1658 : 0 : g_error ("Unknown setter %s for property %s:%s", prop->setter, parent->name, node->name);
1659 : : }
1660 : :
1661 : 0 : blob->setter = (uint16_t) index;
1662 : : }
1663 : : else
1664 : 0 : blob->setter = ACCESSOR_SENTINEL;
1665 : :
1666 [ # # ]: 0 : if (prop->getter != NULL)
1667 : : {
1668 : 0 : int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
1669 : : GI_IR_NODE_FUNCTION,
1670 : 0 : prop->getter);
1671 [ # # ]: 0 : if (index == -1)
1672 : : {
1673 : 0 : g_error ("Unknown getter %s for property %s:%s", prop->getter, parent->name, node->name);
1674 : : }
1675 : :
1676 : 0 : blob->getter = (uint16_t) index;
1677 : : }
1678 : : else
1679 : 0 : blob->getter = ACCESSOR_SENTINEL;
1680 : :
1681 : 0 : gi_ir_node_build_typelib ((GIIrNode *)prop->type,
1682 : : node, build, offset, offset2, NULL);
1683 : : }
1684 : 0 : break;
1685 : :
1686 : 0 : case GI_IR_NODE_FUNCTION:
1687 : : {
1688 : 0 : FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1689 : 0 : SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1690 : 0 : GIIrNodeFunction *function = (GIIrNodeFunction *)node;
1691 : : uint32_t signature;
1692 : : unsigned int n;
1693 : :
1694 : 0 : signature = *offset2;
1695 : 0 : n = g_list_length (function->parameters);
1696 : :
1697 : 0 : *offset += sizeof (FunctionBlob);
1698 : 0 : *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1699 : :
1700 : 0 : blob->blob_type = BLOB_TYPE_FUNCTION;
1701 : 0 : blob->deprecated = function->deprecated;
1702 : 0 : blob->is_static = !function->is_method;
1703 : 0 : blob->setter = FALSE;
1704 : 0 : blob->getter = FALSE;
1705 : 0 : blob->constructor = function->is_constructor;
1706 : 0 : blob->wraps_vfunc = function->wraps_vfunc;
1707 : 0 : blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */
1708 : 0 : blob->index = 0;
1709 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1710 : 0 : blob->symbol = gi_ir_write_string (function->symbol, strings, data, offset2);
1711 : 0 : blob->signature = signature;
1712 : :
1713 [ # # # # ]: 0 : if (function->is_setter || function->is_getter)
1714 : : {
1715 : 0 : int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
1716 : : GI_IR_NODE_PROPERTY,
1717 : 0 : function->property);
1718 [ # # ]: 0 : if (index == -1)
1719 : : {
1720 : 0 : g_error ("Unknown property %s:%s for accessor %s", parent->name, function->property, function->symbol);
1721 : : }
1722 : :
1723 : 0 : blob->setter = function->is_setter;
1724 : 0 : blob->getter = function->is_getter;
1725 : 0 : blob->index = (uint16_t) index;
1726 : : }
1727 : :
1728 : : /* function->result is special since it doesn't appear in the serialized format but
1729 : : * we do want the attributes for it to appear
1730 : : */
1731 : 0 : build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, function->result);
1732 : 0 : build->n_attributes += g_hash_table_size (((GIIrNode *) function->result)->attributes);
1733 : 0 : g_assert (((GIIrNode *) function->result)->offset == 0);
1734 : 0 : ((GIIrNode *) function->result)->offset = signature;
1735 : :
1736 : 0 : g_debug ("building function '%s'", function->symbol);
1737 : :
1738 : 0 : gi_ir_node_build_typelib ((GIIrNode *)function->result->type,
1739 : : node, build, &signature, offset2, NULL);
1740 : :
1741 : 0 : blob2->may_return_null = function->result->nullable;
1742 : 0 : blob2->caller_owns_return_value = function->result->transfer;
1743 : 0 : blob2->caller_owns_return_container = function->result->shallow_transfer;
1744 : 0 : blob2->skip_return = function->result->skip;
1745 : 0 : blob2->instance_transfer_ownership = function->instance_transfer_full;
1746 : 0 : blob2->reserved = 0;
1747 : 0 : blob2->n_arguments = n;
1748 : 0 : blob2->throws = function->throws;
1749 : :
1750 : 0 : signature += 4;
1751 : :
1752 [ # # ]: 0 : for (l = function->parameters; l; l = l->next)
1753 : : {
1754 : 0 : GIIrNode *param = (GIIrNode *)l->data;
1755 : :
1756 : 0 : gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
1757 : : }
1758 : :
1759 : : }
1760 : 0 : break;
1761 : :
1762 : 0 : case GI_IR_NODE_CALLBACK:
1763 : : {
1764 : 0 : CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1765 : 0 : SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1766 : 0 : GIIrNodeFunction *function = (GIIrNodeFunction *)node;
1767 : : uint32_t signature;
1768 : : unsigned int n;
1769 : :
1770 : 0 : signature = *offset2;
1771 : 0 : n = g_list_length (function->parameters);
1772 : :
1773 : 0 : *offset += sizeof (CallbackBlob);
1774 : 0 : *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1775 : :
1776 : 0 : blob->blob_type = BLOB_TYPE_CALLBACK;
1777 : 0 : blob->deprecated = function->deprecated;
1778 : 0 : blob->reserved = 0;
1779 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1780 : 0 : blob->signature = signature;
1781 : :
1782 : 0 : gi_ir_node_build_typelib ((GIIrNode *)function->result->type,
1783 : : node, build, &signature, offset2, NULL);
1784 : :
1785 : 0 : blob2->may_return_null = function->result->nullable;
1786 : 0 : blob2->caller_owns_return_value = function->result->transfer;
1787 : 0 : blob2->caller_owns_return_container = function->result->shallow_transfer;
1788 : 0 : blob2->reserved = 0;
1789 : 0 : blob2->n_arguments = n;
1790 : 0 : blob2->throws = function->throws;
1791 : :
1792 : 0 : signature += 4;
1793 : :
1794 [ # # ]: 0 : for (l = function->parameters; l; l = l->next)
1795 : : {
1796 : 0 : GIIrNode *param = (GIIrNode *)l->data;
1797 : :
1798 : 0 : gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
1799 : : }
1800 : : }
1801 : 0 : break;
1802 : :
1803 : 0 : case GI_IR_NODE_SIGNAL:
1804 : : {
1805 : 0 : SignalBlob *blob = (SignalBlob *)&data[*offset];
1806 : 0 : SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1807 : 0 : GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
1808 : : uint32_t signature;
1809 : : unsigned int n;
1810 : :
1811 : 0 : signature = *offset2;
1812 : 0 : n = g_list_length (signal->parameters);
1813 : :
1814 : 0 : *offset += sizeof (SignalBlob);
1815 : 0 : *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1816 : :
1817 : 0 : blob->deprecated = signal->deprecated;
1818 : 0 : blob->run_first = signal->run_first;
1819 : 0 : blob->run_last = signal->run_last;
1820 : 0 : blob->run_cleanup = signal->run_cleanup;
1821 : 0 : blob->no_recurse = signal->no_recurse;
1822 : 0 : blob->detailed = signal->detailed;
1823 : 0 : blob->action = signal->action;
1824 : 0 : blob->no_hooks = signal->no_hooks;
1825 : 0 : blob->has_class_closure = 0; /* FIXME */
1826 : 0 : blob->true_stops_emit = 0; /* FIXME */
1827 : 0 : blob->reserved = 0;
1828 : 0 : blob->class_closure = 0; /* FIXME */
1829 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1830 : 0 : blob->signature = signature;
1831 : :
1832 : : /* signal->result is special since it doesn't appear in the serialized format but
1833 : : * we do want the attributes for it to appear
1834 : : */
1835 : 0 : build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, signal->result);
1836 : 0 : build->n_attributes += g_hash_table_size (((GIIrNode *) signal->result)->attributes);
1837 : 0 : g_assert (((GIIrNode *) signal->result)->offset == 0);
1838 : 0 : ((GIIrNode *) signal->result)->offset = signature;
1839 : :
1840 : 0 : gi_ir_node_build_typelib ((GIIrNode *)signal->result->type,
1841 : : node, build, &signature, offset2, NULL);
1842 : :
1843 : 0 : blob2->may_return_null = signal->result->nullable;
1844 : 0 : blob2->caller_owns_return_value = signal->result->transfer;
1845 : 0 : blob2->caller_owns_return_container = signal->result->shallow_transfer;
1846 : 0 : blob2->instance_transfer_ownership = signal->instance_transfer_full;
1847 : 0 : blob2->reserved = 0;
1848 : 0 : blob2->n_arguments = n;
1849 : :
1850 : 0 : signature += 4;
1851 : :
1852 [ # # ]: 0 : for (l = signal->parameters; l; l = l->next)
1853 : : {
1854 : 0 : GIIrNode *param = (GIIrNode *)l->data;
1855 : :
1856 : 0 : gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
1857 : : }
1858 : : }
1859 : 0 : break;
1860 : :
1861 : 0 : case GI_IR_NODE_VFUNC:
1862 : : {
1863 : 0 : VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1864 : 0 : SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1865 : 0 : GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
1866 : : uint32_t signature;
1867 : : unsigned int n;
1868 : :
1869 : 0 : signature = *offset2;
1870 : 0 : n = g_list_length (vfunc->parameters);
1871 : :
1872 : 0 : *offset += sizeof (VFuncBlob);
1873 : 0 : *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1874 : :
1875 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1876 : 0 : blob->must_chain_up = 0; /* FIXME */
1877 : 0 : blob->must_be_implemented = 0; /* FIXME */
1878 : 0 : blob->must_not_be_implemented = 0; /* FIXME */
1879 : 0 : blob->class_closure = 0; /* FIXME */
1880 : 0 : blob->throws = vfunc->throws; /* Deprecated. Also stored in SignatureBlob. */
1881 : 0 : blob->reserved = 0;
1882 : :
1883 [ # # ]: 0 : if (vfunc->invoker)
1884 : : {
1885 : 0 : int index = get_index_of_member_type ((GIIrNodeInterface*)parent, GI_IR_NODE_FUNCTION, vfunc->invoker);
1886 [ # # ]: 0 : if (index == -1)
1887 : : {
1888 : 0 : g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
1889 : : }
1890 : 0 : blob->invoker = (uint16_t) index;
1891 : : }
1892 : : else
1893 : 0 : blob->invoker = 0x3ff; /* max of 10 bits */
1894 : :
1895 : 0 : blob->struct_offset = vfunc->offset;
1896 : 0 : blob->reserved2 = 0;
1897 : 0 : blob->signature = signature;
1898 : :
1899 : 0 : gi_ir_node_build_typelib ((GIIrNode *)vfunc->result->type,
1900 : : node, build, &signature, offset2, NULL);
1901 : :
1902 : 0 : blob2->may_return_null = vfunc->result->nullable;
1903 : 0 : blob2->caller_owns_return_value = vfunc->result->transfer;
1904 : 0 : blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1905 : 0 : blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
1906 : 0 : blob2->reserved = 0;
1907 : 0 : blob2->n_arguments = n;
1908 : 0 : blob2->throws = vfunc->throws;
1909 : :
1910 : 0 : signature += 4;
1911 : :
1912 [ # # ]: 0 : for (l = vfunc->parameters; l; l = l->next)
1913 : : {
1914 : 0 : GIIrNode *param = (GIIrNode *)l->data;
1915 : :
1916 : 0 : gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
1917 : : }
1918 : : }
1919 : 0 : break;
1920 : :
1921 : 0 : case GI_IR_NODE_PARAM:
1922 : : {
1923 : 0 : ArgBlob *blob = (ArgBlob *)&data[*offset];
1924 : 0 : GIIrNodeParam *param = (GIIrNodeParam *)node;
1925 : :
1926 : : /* The offset for this one is smaller than the struct because
1927 : : * we recursively build the simple type inline here below.
1928 : : */
1929 : 0 : *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
1930 : :
1931 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1932 : 0 : blob->in = param->in;
1933 : 0 : blob->out = param->out;
1934 : 0 : blob->caller_allocates = param->caller_allocates;
1935 : 0 : blob->nullable = param->nullable;
1936 : 0 : blob->skip = param->skip;
1937 : 0 : blob->optional = param->optional;
1938 : 0 : blob->transfer_ownership = param->transfer;
1939 : 0 : blob->transfer_container_ownership = param->shallow_transfer;
1940 : 0 : blob->return_value = param->retval;
1941 : 0 : blob->scope = param->scope;
1942 : 0 : blob->reserved = 0;
1943 : 0 : blob->closure = param->closure;
1944 : 0 : blob->destroy = param->destroy;
1945 : :
1946 : 0 : gi_ir_node_build_typelib ((GIIrNode *)param->type, node, build, offset, offset2, NULL);
1947 : : }
1948 : 0 : break;
1949 : :
1950 : 0 : case GI_IR_NODE_STRUCT:
1951 : : {
1952 : 0 : StructBlob *blob = (StructBlob *)&data[*offset];
1953 : 0 : GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
1954 : : GList *members;
1955 : :
1956 : 0 : blob->blob_type = BLOB_TYPE_STRUCT;
1957 : 0 : blob->foreign = struct_->foreign;
1958 : 0 : blob->deprecated = struct_->deprecated;
1959 : 0 : blob->is_gtype_struct = struct_->is_gtype_struct;
1960 : 0 : blob->reserved = 0;
1961 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
1962 : 0 : blob->alignment = struct_->alignment;
1963 : 0 : blob->size = struct_->size;
1964 : :
1965 [ # # ]: 0 : if (struct_->gtype_name)
1966 : : {
1967 : 0 : blob->unregistered = FALSE;
1968 : 0 : blob->gtype_name = gi_ir_write_string (struct_->gtype_name, strings, data, offset2);
1969 : 0 : blob->gtype_init = gi_ir_write_string (struct_->gtype_init, strings, data, offset2);
1970 : : }
1971 : : else
1972 : : {
1973 : 0 : blob->unregistered = TRUE;
1974 : 0 : blob->gtype_name = 0;
1975 : 0 : blob->gtype_init = 0;
1976 : : }
1977 : :
1978 [ # # ]: 0 : if (struct_->copy_func)
1979 : 0 : blob->copy_func = gi_ir_write_string (struct_->copy_func, strings, data, offset2);
1980 [ # # ]: 0 : if (struct_->free_func)
1981 : 0 : blob->free_func = gi_ir_write_string (struct_->free_func, strings, data, offset2);
1982 : :
1983 : 0 : blob->n_fields = 0;
1984 : 0 : blob->n_methods = 0;
1985 : :
1986 : 0 : *offset += sizeof (StructBlob);
1987 : :
1988 : 0 : members = g_list_copy (struct_->members);
1989 : :
1990 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
1991 : : node, build, offset, offset2, NULL);
1992 : :
1993 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
1994 : : node, build, offset, offset2, NULL);
1995 : :
1996 : 0 : gi_ir_node_check_unhandled_members (&members, node->type);
1997 : :
1998 : 0 : g_assert (members == NULL);
1999 : : }
2000 : 0 : break;
2001 : :
2002 : 0 : case GI_IR_NODE_BOXED:
2003 : : {
2004 : 0 : StructBlob *blob = (StructBlob *)&data[*offset];
2005 : 0 : GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
2006 : : GList *members;
2007 : :
2008 : 0 : blob->blob_type = BLOB_TYPE_BOXED;
2009 : 0 : blob->deprecated = boxed->deprecated;
2010 : 0 : blob->unregistered = FALSE;
2011 : 0 : blob->reserved = 0;
2012 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2013 : 0 : blob->gtype_name = gi_ir_write_string (boxed->gtype_name, strings, data, offset2);
2014 : 0 : blob->gtype_init = gi_ir_write_string (boxed->gtype_init, strings, data, offset2);
2015 : 0 : blob->alignment = boxed->alignment;
2016 : 0 : blob->size = boxed->size;
2017 : :
2018 : 0 : blob->n_fields = 0;
2019 : 0 : blob->n_methods = 0;
2020 : :
2021 : 0 : *offset += sizeof (StructBlob);
2022 : :
2023 : 0 : members = g_list_copy (boxed->members);
2024 : :
2025 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
2026 : : node, build, offset, offset2, NULL);
2027 : :
2028 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
2029 : : node, build, offset, offset2, NULL);
2030 : :
2031 : 0 : gi_ir_node_check_unhandled_members (&members, node->type);
2032 : :
2033 : 0 : g_assert (members == NULL);
2034 : : }
2035 : 0 : break;
2036 : :
2037 : 0 : case GI_IR_NODE_UNION:
2038 : : {
2039 : 0 : UnionBlob *blob = (UnionBlob *)&data[*offset];
2040 : 0 : GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
2041 : : GList *members;
2042 : :
2043 : 0 : blob->blob_type = BLOB_TYPE_UNION;
2044 : 0 : blob->deprecated = union_->deprecated;
2045 : 0 : blob->reserved = 0;
2046 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2047 : 0 : blob->alignment = union_->alignment;
2048 : 0 : blob->size = union_->size;
2049 [ # # ]: 0 : if (union_->gtype_name)
2050 : : {
2051 : 0 : blob->unregistered = FALSE;
2052 : 0 : blob->gtype_name = gi_ir_write_string (union_->gtype_name, strings, data, offset2);
2053 : 0 : blob->gtype_init = gi_ir_write_string (union_->gtype_init, strings, data, offset2);
2054 : : }
2055 : : else
2056 : : {
2057 : 0 : blob->unregistered = TRUE;
2058 : 0 : blob->gtype_name = 0;
2059 : 0 : blob->gtype_init = 0;
2060 : : }
2061 : :
2062 : 0 : blob->n_fields = 0;
2063 : 0 : blob->n_functions = 0;
2064 : :
2065 : 0 : blob->discriminator_offset = union_->discriminator_offset;
2066 : :
2067 [ # # ]: 0 : if (union_->copy_func)
2068 : 0 : blob->copy_func = gi_ir_write_string (union_->copy_func, strings, data, offset2);
2069 [ # # ]: 0 : if (union_->free_func)
2070 : 0 : blob->free_func = gi_ir_write_string (union_->free_func, strings, data, offset2);
2071 : :
2072 : : /* We don't support Union discriminators right now. */
2073 : : /*
2074 : : if (union_->discriminator_type)
2075 : : {
2076 : : *offset += 28;
2077 : : blob->discriminated = TRUE;
2078 : : gi_ir_node_build_typelib ((GIIrNode *)union_->discriminator_type,
2079 : : build, offset, offset2, NULL);
2080 : : }
2081 : : else
2082 : : {
2083 : : */
2084 : 0 : *offset += sizeof (UnionBlob);
2085 : 0 : blob->discriminated = FALSE;
2086 : 0 : blob->discriminator_type.offset = 0;
2087 : :
2088 : 0 : members = g_list_copy (union_->members);
2089 : :
2090 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
2091 : : node, build, offset, offset2, NULL);
2092 : :
2093 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_functions,
2094 : : node, build, offset, offset2, NULL);
2095 : :
2096 : 0 : gi_ir_node_check_unhandled_members (&members, node->type);
2097 : :
2098 : 0 : g_assert (members == NULL);
2099 : :
2100 [ # # ]: 0 : if (union_->discriminator_type)
2101 : : {
2102 [ # # ]: 0 : for (l = union_->discriminators; l; l = l->next)
2103 : : {
2104 : 0 : GIIrNode *member = (GIIrNode *)l->data;
2105 : :
2106 : 0 : gi_ir_node_build_typelib (member, node, build, offset, offset2, NULL);
2107 : : }
2108 : : }
2109 : : }
2110 : 0 : break;
2111 : :
2112 : 0 : case GI_IR_NODE_ENUM:
2113 : : case GI_IR_NODE_FLAGS:
2114 : : {
2115 : 0 : EnumBlob *blob = (EnumBlob *)&data[*offset];
2116 : 0 : GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
2117 : :
2118 : 0 : *offset += sizeof (EnumBlob);
2119 : :
2120 [ # # ]: 0 : if (node->type == GI_IR_NODE_ENUM)
2121 : 0 : blob->blob_type = BLOB_TYPE_ENUM;
2122 : : else
2123 : 0 : blob->blob_type = BLOB_TYPE_FLAGS;
2124 : :
2125 : 0 : blob->deprecated = enum_->deprecated;
2126 : 0 : blob->reserved = 0;
2127 : 0 : blob->storage_type = enum_->storage_type;
2128 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2129 [ # # ]: 0 : if (enum_->gtype_name)
2130 : : {
2131 : 0 : blob->unregistered = FALSE;
2132 : 0 : blob->gtype_name = gi_ir_write_string (enum_->gtype_name, strings, data, offset2);
2133 : 0 : blob->gtype_init = gi_ir_write_string (enum_->gtype_init, strings, data, offset2);
2134 : : }
2135 : : else
2136 : : {
2137 : 0 : blob->unregistered = TRUE;
2138 : 0 : blob->gtype_name = 0;
2139 : 0 : blob->gtype_init = 0;
2140 : : }
2141 [ # # ]: 0 : if (enum_->error_domain)
2142 : 0 : blob->error_domain = gi_ir_write_string (enum_->error_domain, strings, data, offset2);
2143 : : else
2144 : 0 : blob->error_domain = 0;
2145 : :
2146 : 0 : blob->n_values = 0;
2147 : 0 : blob->n_methods = 0;
2148 : :
2149 [ # # ]: 0 : for (l = enum_->values; l; l = l->next)
2150 : : {
2151 : 0 : GIIrNode *value = (GIIrNode *)l->data;
2152 : :
2153 : 0 : blob->n_values++;
2154 : 0 : gi_ir_node_build_typelib (value, node, build, offset, offset2, NULL);
2155 : : }
2156 : :
2157 [ # # ]: 0 : for (l = enum_->methods; l; l = l->next)
2158 : : {
2159 : 0 : GIIrNode *method = (GIIrNode *)l->data;
2160 : :
2161 : 0 : blob->n_methods++;
2162 : 0 : gi_ir_node_build_typelib (method, node, build, offset, offset2, NULL);
2163 : : }
2164 : : }
2165 : 0 : break;
2166 : :
2167 : 0 : case GI_IR_NODE_OBJECT:
2168 : : {
2169 : 0 : ObjectBlob *blob = (ObjectBlob *)&data[*offset];
2170 : 0 : GIIrNodeInterface *object = (GIIrNodeInterface *)node;
2171 : : GList *members;
2172 : :
2173 : 0 : blob->blob_type = BLOB_TYPE_OBJECT;
2174 : 0 : blob->abstract = object->abstract;
2175 : 0 : blob->fundamental = object->fundamental;
2176 : 0 : blob->final_ = object->final_;
2177 : 0 : blob->deprecated = object->deprecated;
2178 : 0 : blob->reserved = 0;
2179 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2180 : 0 : blob->gtype_name = gi_ir_write_string (object->gtype_name, strings, data, offset2);
2181 : 0 : blob->gtype_init = gi_ir_write_string (object->gtype_init, strings, data, offset2);
2182 [ # # ]: 0 : if (object->ref_func)
2183 : 0 : blob->ref_func = gi_ir_write_string (object->ref_func, strings, data, offset2);
2184 [ # # ]: 0 : if (object->unref_func)
2185 : 0 : blob->unref_func = gi_ir_write_string (object->unref_func, strings, data, offset2);
2186 [ # # ]: 0 : if (object->set_value_func)
2187 : 0 : blob->set_value_func = gi_ir_write_string (object->set_value_func, strings, data, offset2);
2188 [ # # ]: 0 : if (object->get_value_func)
2189 : 0 : blob->get_value_func = gi_ir_write_string (object->get_value_func, strings, data, offset2);
2190 [ # # ]: 0 : if (object->parent)
2191 : 0 : blob->parent = find_entry (build, object->parent);
2192 : : else
2193 : 0 : blob->parent = 0;
2194 [ # # ]: 0 : if (object->glib_type_struct)
2195 : 0 : blob->gtype_struct = find_entry (build, object->glib_type_struct);
2196 : : else
2197 : 0 : blob->gtype_struct = 0;
2198 : :
2199 : 0 : blob->n_interfaces = 0;
2200 : 0 : blob->n_fields = 0;
2201 : 0 : blob->n_properties = 0;
2202 : 0 : blob->n_methods = 0;
2203 : 0 : blob->n_signals = 0;
2204 : 0 : blob->n_vfuncs = 0;
2205 : 0 : blob->n_constants = 0;
2206 : 0 : blob->n_field_callbacks = 0;
2207 : :
2208 : 0 : *offset += sizeof(ObjectBlob);
2209 [ # # ]: 0 : for (l = object->interfaces; l; l = l->next)
2210 : : {
2211 : 0 : blob->n_interfaces++;
2212 : 0 : *(uint16_t *)&data[*offset] = find_entry (build, (char *)l->data);
2213 : 0 : *offset += 2;
2214 : : }
2215 : :
2216 : 0 : members = g_list_copy (object->members);
2217 : :
2218 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2219 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
2220 : : node, build, offset, offset2, &blob->n_field_callbacks);
2221 : :
2222 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2223 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_PROPERTY, &blob->n_properties,
2224 : : node, build, offset, offset2, NULL);
2225 : :
2226 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2227 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
2228 : : node, build, offset, offset2, NULL);
2229 : :
2230 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2231 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_SIGNAL, &blob->n_signals,
2232 : : node, build, offset, offset2, NULL);
2233 : :
2234 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2235 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_VFUNC, &blob->n_vfuncs,
2236 : : node, build, offset, offset2, NULL);
2237 : :
2238 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2239 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_CONSTANT, &blob->n_constants,
2240 : : node, build, offset, offset2, NULL);
2241 : :
2242 : 0 : gi_ir_node_check_unhandled_members (&members, node->type);
2243 : :
2244 : 0 : g_assert (members == NULL);
2245 : : }
2246 : 0 : break;
2247 : :
2248 : 0 : case GI_IR_NODE_INTERFACE:
2249 : : {
2250 : 0 : InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
2251 : 0 : GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
2252 : : GList *members;
2253 : :
2254 : 0 : blob->blob_type = BLOB_TYPE_INTERFACE;
2255 : 0 : blob->deprecated = iface->deprecated;
2256 : 0 : blob->reserved = 0;
2257 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2258 : 0 : blob->gtype_name = gi_ir_write_string (iface->gtype_name, strings, data, offset2);
2259 : 0 : blob->gtype_init = gi_ir_write_string (iface->gtype_init, strings, data, offset2);
2260 [ # # ]: 0 : if (iface->glib_type_struct)
2261 : 0 : blob->gtype_struct = find_entry (build, iface->glib_type_struct);
2262 : : else
2263 : 0 : blob->gtype_struct = 0;
2264 : 0 : blob->n_prerequisites = 0;
2265 : 0 : blob->n_properties = 0;
2266 : 0 : blob->n_methods = 0;
2267 : 0 : blob->n_signals = 0;
2268 : 0 : blob->n_vfuncs = 0;
2269 : 0 : blob->n_constants = 0;
2270 : :
2271 : 0 : *offset += sizeof (InterfaceBlob);
2272 [ # # ]: 0 : for (l = iface->prerequisites; l; l = l->next)
2273 : : {
2274 : 0 : blob->n_prerequisites++;
2275 : 0 : *(uint16_t *)&data[*offset] = find_entry (build, (char *)l->data);
2276 : 0 : *offset += 2;
2277 : : }
2278 : :
2279 : 0 : members = g_list_copy (iface->members);
2280 : :
2281 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2282 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_PROPERTY, &blob->n_properties,
2283 : : node, build, offset, offset2, NULL);
2284 : :
2285 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2286 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
2287 : : node, build, offset, offset2, NULL);
2288 : :
2289 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2290 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_SIGNAL, &blob->n_signals,
2291 : : node, build, offset, offset2, NULL);
2292 : :
2293 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2294 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_VFUNC, &blob->n_vfuncs,
2295 : : node, build, offset, offset2, NULL);
2296 : :
2297 : 0 : *offset = ALIGN_VALUE (*offset, 4);
2298 : 0 : gi_ir_node_build_members (&members, GI_IR_NODE_CONSTANT, &blob->n_constants,
2299 : : node, build, offset, offset2, NULL);
2300 : :
2301 : 0 : gi_ir_node_check_unhandled_members (&members, node->type);
2302 : :
2303 : 0 : g_assert (members == NULL);
2304 : : }
2305 : 0 : break;
2306 : :
2307 : :
2308 : 0 : case GI_IR_NODE_VALUE:
2309 : : {
2310 : 0 : GIIrNodeValue *value = (GIIrNodeValue *)node;
2311 : 0 : ValueBlob *blob = (ValueBlob *)&data[*offset];
2312 : 0 : *offset += sizeof (ValueBlob);
2313 : :
2314 : 0 : blob->deprecated = value->deprecated;
2315 : 0 : blob->reserved = 0;
2316 : 0 : blob->unsigned_value = value->value >= 0 ? 1 : 0;
2317 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2318 : 0 : blob->value = (int32_t) value->value;
2319 : : }
2320 : 0 : break;
2321 : :
2322 : 0 : case GI_IR_NODE_CONSTANT:
2323 : : {
2324 : 0 : GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
2325 : 0 : ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2326 : : uint32_t pos;
2327 : :
2328 : 0 : pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
2329 : 0 : *offset += sizeof (ConstantBlob);
2330 : :
2331 : 0 : blob->blob_type = BLOB_TYPE_CONSTANT;
2332 : 0 : blob->deprecated = constant->deprecated;
2333 : 0 : blob->reserved = 0;
2334 : 0 : blob->name = gi_ir_write_string (node->name, strings, data, offset2);
2335 : :
2336 : 0 : blob->offset = *offset2;
2337 [ # # # # : 0 : switch (constant->type->tag)
# # # # #
# # # # ]
2338 : : {
2339 : 0 : case GI_TYPE_TAG_BOOLEAN:
2340 : 0 : blob->size = 4;
2341 : 0 : *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2342 : 0 : break;
2343 : 0 : case GI_TYPE_TAG_INT8:
2344 : 0 : blob->size = 1;
2345 : 0 : *(int8_t *)&data[blob->offset] = (int8_t) parse_int_value (constant->value);
2346 : 0 : break;
2347 : 0 : case GI_TYPE_TAG_UINT8:
2348 : 0 : blob->size = 1;
2349 : 0 : *(uint8_t *)&data[blob->offset] = (uint8_t) parse_uint_value (constant->value);
2350 : 0 : break;
2351 : 0 : case GI_TYPE_TAG_INT16:
2352 : 0 : blob->size = 2;
2353 : 0 : *(int16_t *)&data[blob->offset] = (int16_t) parse_int_value (constant->value);
2354 : 0 : break;
2355 : 0 : case GI_TYPE_TAG_UINT16:
2356 : 0 : blob->size = 2;
2357 : 0 : *(uint16_t *)&data[blob->offset] = (uint16_t) parse_uint_value (constant->value);
2358 : 0 : break;
2359 : 0 : case GI_TYPE_TAG_INT32:
2360 : 0 : blob->size = 4;
2361 : 0 : *(int32_t *)&data[blob->offset] = (int32_t) parse_int_value (constant->value);
2362 : 0 : break;
2363 : 0 : case GI_TYPE_TAG_UINT32:
2364 : 0 : blob->size = 4;
2365 : 0 : *(uint32_t*)&data[blob->offset] = (uint32_t) parse_uint_value (constant->value);
2366 : 0 : break;
2367 : 0 : case GI_TYPE_TAG_INT64:
2368 : 0 : blob->size = 8;
2369 : 0 : DO_ALIGNED_COPY (&data[blob->offset], parse_int_value (constant->value), int64_t);
2370 : 0 : break;
2371 : 0 : case GI_TYPE_TAG_UINT64:
2372 : 0 : blob->size = 8;
2373 : 0 : DO_ALIGNED_COPY (&data[blob->offset], parse_uint_value (constant->value), uint64_t);
2374 : 0 : break;
2375 : 0 : case GI_TYPE_TAG_FLOAT:
2376 : 0 : blob->size = sizeof (float);
2377 : 0 : DO_ALIGNED_COPY (&data[blob->offset], parse_float_value (constant->value), float);
2378 : 0 : break;
2379 : 0 : case GI_TYPE_TAG_DOUBLE:
2380 : 0 : blob->size = sizeof (double);
2381 : 0 : DO_ALIGNED_COPY (&data[blob->offset], parse_float_value (constant->value), double);
2382 : 0 : break;
2383 : 0 : case GI_TYPE_TAG_UTF8:
2384 : : case GI_TYPE_TAG_FILENAME:
2385 : 0 : blob->size = strlen (constant->value) + 1;
2386 : 0 : memcpy (&data[blob->offset], constant->value, blob->size);
2387 : 0 : break;
2388 : 0 : default:
2389 : 0 : break;
2390 : : }
2391 : 0 : *offset2 += ALIGN_VALUE (blob->size, 4);
2392 : :
2393 : 0 : gi_ir_node_build_typelib ((GIIrNode *)constant->type, node, build, &pos, offset2, NULL);
2394 : : }
2395 : 0 : break;
2396 : 0 : default:
2397 : : g_assert_not_reached ();
2398 : : }
2399 : :
2400 [ # # # # : 0 : g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
# # ]
2401 : : node->name ? "'" : "",
2402 : : node->name ? node->name : "",
2403 : : node->name ? "' " : "",
2404 : : node, gi_ir_node_type_to_string (node->type),
2405 : : old_offset, *offset, old_offset2, *offset2);
2406 : :
2407 [ # # ]: 0 : if (*offset2 - old_offset2 + *offset - old_offset > gi_ir_node_get_full_size (node))
2408 : 0 : g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
2409 : : *offset, old_offset, *offset2, old_offset2, gi_ir_node_get_full_size (node));
2410 : :
2411 [ # # ]: 0 : if (appended_stack)
2412 : 0 : build->stack = g_list_delete_link (build->stack, build->stack);
2413 : 0 : }
2414 : :
2415 : : /* if str is already in the pool, return previous location, otherwise write str
2416 : : * to the typelib at offset, put it in the pool and update offset. If the
2417 : : * typelib is not large enough to hold the string, reallocate it.
2418 : : */
2419 : : uint32_t
2420 : 0 : gi_ir_write_string (const char *str,
2421 : : GHashTable *strings,
2422 : : uint8_t *data,
2423 : : uint32_t *offset)
2424 : : {
2425 : : uint32_t start;
2426 : : void *value;
2427 : :
2428 : 0 : string_count += 1;
2429 : 0 : string_size += strlen (str);
2430 : :
2431 : 0 : value = g_hash_table_lookup (strings, str);
2432 : :
2433 [ # # ]: 0 : if (value)
2434 : 0 : return GPOINTER_TO_UINT (value);
2435 : :
2436 : 0 : unique_string_count += 1;
2437 : 0 : unique_string_size += strlen (str);
2438 : :
2439 : 0 : g_hash_table_insert (strings, (void *)str, GUINT_TO_POINTER (*offset));
2440 : :
2441 : 0 : start = *offset;
2442 : 0 : *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2443 : :
2444 : 0 : strcpy ((char *)&data[start], str);
2445 : :
2446 : 0 : return start;
2447 : : }
2448 : :
|