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