girnode.c 58.9 KB
Newer Older
1
/* GObject introspection: Typelib creation
Matthias Clasen's avatar
Matthias Clasen committed
2 3
 *
 * Copyright (C) 2005 Matthias Clasen
4
 * Copyright (C) 2008,2009 Red Hat, Inc.
Matthias Clasen's avatar
Matthias Clasen committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
Matthias Clasen's avatar
Matthias Clasen committed
25

26 27
#include "girmodule.h"
#include "girnode.h"
Philip Van Hoof's avatar
Philip Van Hoof committed
28
#include "gtypelib.h"
Matthias Clasen's avatar
Matthias Clasen committed
29

30 31 32 33 34 35 36 37
static gulong string_count = 0;
static gulong unique_string_count = 0;
static gulong string_size = 0;
static gulong unique_string_size = 0;
static gulong types_count = 0;
static gulong unique_types_count = 0;

void
38
_g_irnode_init_stats (void)
39 40 41 42 43 44 45 46 47 48
{
  string_count = 0;
  unique_string_count = 0;
  string_size = 0;
  unique_string_size = 0;
  types_count = 0;
  unique_types_count = 0;
}

void
49
_g_irnode_dump_stats (void)
50 51 52 53 54 55 56 57 58 59
{
  g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
	     unique_string_count, string_count, unique_string_size, string_size);
  g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
}

#define ALIGN_VALUE(this, boundary) \
  (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))


60
const gchar *
61
g_ir_node_type_to_string (GIrNodeTypeId type)
Matthias Clasen's avatar
Matthias Clasen committed
62
{
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  switch (type)
    {
    case G_IR_NODE_FUNCTION:
      return "function";
    case G_IR_NODE_CALLBACK:
      return "callback";
    case G_IR_NODE_PARAM:
      return "param";
    case G_IR_NODE_TYPE:
      return "type";
    case G_IR_NODE_OBJECT:
      return "object";
    case G_IR_NODE_INTERFACE:
      return "interface";
    case G_IR_NODE_SIGNAL:
      return "signal";
    case G_IR_NODE_PROPERTY:
      return "property";
    case G_IR_NODE_VFUNC:
      return "vfunc";
    case G_IR_NODE_FIELD:
      return "field";
    case G_IR_NODE_ENUM:
      return "enum";
    case G_IR_NODE_FLAGS:
      return "flags";
    case G_IR_NODE_BOXED:
      return "boxed";
    case G_IR_NODE_STRUCT:
      return "struct";
    case G_IR_NODE_VALUE:
      return "value";
    case G_IR_NODE_CONSTANT:
      return "constant";
    case G_IR_NODE_ERROR_DOMAIN:
      return "error-domain";
    case G_IR_NODE_XREF:
      return "xref";
    case G_IR_NODE_UNION:
      return "union";
    default:
      return "unknown";
    }
}
Matthias Clasen's avatar
Matthias Clasen committed
107

108 109 110 111 112 113 114 115 116 117
GIrNode *
g_ir_node_new (GIrNodeTypeId type)
{
  GIrNode *node = NULL;

  switch (type)
    {
   case G_IR_NODE_FUNCTION:
   case G_IR_NODE_CALLBACK:
      node = g_malloc0 (sizeof (GIrNodeFunction));
Matthias Clasen's avatar
Matthias Clasen committed
118 119
      break;

120 121
   case G_IR_NODE_PARAM:
      node = g_malloc0 (sizeof (GIrNodeParam));
Matthias Clasen's avatar
Matthias Clasen committed
122 123
      break;

124 125
   case G_IR_NODE_TYPE:
      node = g_malloc0 (sizeof (GIrNodeType));
Matthias Clasen's avatar
Matthias Clasen committed
126 127
      break;

128 129 130
    case G_IR_NODE_OBJECT:
    case G_IR_NODE_INTERFACE:
      node = g_malloc0 (sizeof (GIrNodeInterface));
Matthias Clasen's avatar
Matthias Clasen committed
131 132
      break;

133 134
    case G_IR_NODE_SIGNAL:
      node = g_malloc0 (sizeof (GIrNodeSignal));
Matthias Clasen's avatar
Matthias Clasen committed
135 136
      break;

137 138
    case G_IR_NODE_PROPERTY:
      node = g_malloc0 (sizeof (GIrNodeProperty));
Matthias Clasen's avatar
Matthias Clasen committed
139 140
      break;

141 142
    case G_IR_NODE_VFUNC:
      node = g_malloc0 (sizeof (GIrNodeFunction));
Matthias Clasen's avatar
Matthias Clasen committed
143 144
      break;

145 146
    case G_IR_NODE_FIELD:
      node = g_malloc0 (sizeof (GIrNodeField));
Matthias Clasen's avatar
Matthias Clasen committed
147 148
      break;

149 150 151
    case G_IR_NODE_ENUM:
    case G_IR_NODE_FLAGS:
      node = g_malloc0 (sizeof (GIrNodeEnum));
Matthias Clasen's avatar
Matthias Clasen committed
152 153
      break;

154 155
    case G_IR_NODE_BOXED:
      node = g_malloc0 (sizeof (GIrNodeBoxed));
Matthias Clasen's avatar
Matthias Clasen committed
156 157
      break;

158 159
    case G_IR_NODE_STRUCT:
      node = g_malloc0 (sizeof (GIrNodeStruct));
Matthias Clasen's avatar
Matthias Clasen committed
160 161
      break;

162 163
    case G_IR_NODE_VALUE:
      node = g_malloc0 (sizeof (GIrNodeValue));
Matthias Clasen's avatar
Matthias Clasen committed
164 165
      break;

166 167
    case G_IR_NODE_CONSTANT:
      node = g_malloc0 (sizeof (GIrNodeConstant));
Matthias Clasen's avatar
Matthias Clasen committed
168 169
      break;

170 171
    case G_IR_NODE_ERROR_DOMAIN:
      node = g_malloc0 (sizeof (GIrNodeErrorDomain));
Matthias Clasen's avatar
Matthias Clasen committed
172 173
      break;

174 175
    case G_IR_NODE_XREF:
      node = g_malloc0 (sizeof (GIrNodeXRef));
Matthias Clasen's avatar
Matthias Clasen committed
176 177
      break;

178 179
    case G_IR_NODE_UNION:
      node = g_malloc0 (sizeof (GIrNodeUnion));
Matthias Clasen's avatar
Matthias Clasen committed
180 181
      break;

Matthias Clasen's avatar
Matthias Clasen committed
182 183 184 185 186 187
    default:
      g_error ("Unhandled node type %d\n", type);
      break;
    }

  node->type = type;
188 189 190
  node->offset = 0;
  node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
                                            g_free, g_free);
Matthias Clasen's avatar
Matthias Clasen committed
191 192 193 194 195

  return node;
}

void
196
g_ir_node_free (GIrNode *node)
Matthias Clasen's avatar
Matthias Clasen committed
197 198 199
{
  GList *l;

200 201 202
  if (node == NULL)
    return;

Matthias Clasen's avatar
Matthias Clasen committed
203 204
  switch (node->type)
    {
205 206
    case G_IR_NODE_FUNCTION:
    case G_IR_NODE_CALLBACK:
Matthias Clasen's avatar
Matthias Clasen committed
207
      {
208
	GIrNodeFunction *function = (GIrNodeFunction *)node;
Matthias Clasen's avatar
Matthias Clasen committed
209 210
	
	g_free (node->name);
211
	g_free (function->symbol);
212
	g_ir_node_free ((GIrNode *)function->result);
Matthias Clasen's avatar
Matthias Clasen committed
213
	for (l = function->parameters; l; l = l->next)
214
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
215 216 217 218
	g_list_free (function->parameters);
      }
      break;

219
    case G_IR_NODE_TYPE:
Matthias Clasen's avatar
Matthias Clasen committed
220
      {
221
	GIrNodeType *type = (GIrNodeType *)node;
Matthias Clasen's avatar
Matthias Clasen committed
222 223
	
	g_free (node->name);
224 225
	g_ir_node_free ((GIrNode *)type->parameter_type1);
	g_ir_node_free ((GIrNode *)type->parameter_type2);
Matthias Clasen's avatar
Matthias Clasen committed
226 227 228 229 230 231 232

	g_free (type->interface);
	g_strfreev (type->errors);

      }
      break;

233
    case G_IR_NODE_PARAM:
Matthias Clasen's avatar
Matthias Clasen committed
234
      {
235
	GIrNodeParam *param = (GIrNodeParam *)node;
Matthias Clasen's avatar
Matthias Clasen committed
236 237
	
	g_free (node->name);
238
	g_ir_node_free ((GIrNode *)param->type);
Matthias Clasen's avatar
Matthias Clasen committed
239 240 241
      }
      break;

242
    case G_IR_NODE_PROPERTY:
Matthias Clasen's avatar
Matthias Clasen committed
243
      {
244
	GIrNodeProperty *property = (GIrNodeProperty *)node;
Matthias Clasen's avatar
Matthias Clasen committed
245 246
	
	g_free (node->name);
247
	g_ir_node_free ((GIrNode *)property->type);
Matthias Clasen's avatar
Matthias Clasen committed
248 249 250
      }
      break;

251
    case G_IR_NODE_SIGNAL:
Matthias Clasen's avatar
Matthias Clasen committed
252
      {
253
	GIrNodeSignal *signal = (GIrNodeSignal *)node;
Matthias Clasen's avatar
Matthias Clasen committed
254 255 256
	
	g_free (node->name);
	for (l = signal->parameters; l; l = l->next)
257
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
258
	g_list_free (signal->parameters);
259
	g_ir_node_free ((GIrNode *)signal->result);
Matthias Clasen's avatar
Matthias Clasen committed
260 261 262
      }
      break;

263
    case G_IR_NODE_VFUNC:
Matthias Clasen's avatar
Matthias Clasen committed
264
      {
265
	GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
Matthias Clasen's avatar
Matthias Clasen committed
266 267
	
	g_free (node->name);
268
	g_free (vfunc->invoker);
Matthias Clasen's avatar
Matthias Clasen committed
269
	for (l = vfunc->parameters; l; l = l->next)
270
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
271
	g_list_free (vfunc->parameters);
272
	g_ir_node_free ((GIrNode *)vfunc->result);
Matthias Clasen's avatar
Matthias Clasen committed
273 274 275
      }
      break;

276
    case G_IR_NODE_FIELD:
Matthias Clasen's avatar
Matthias Clasen committed
277
      {
278
	GIrNodeField *field = (GIrNodeField *)node;
Matthias Clasen's avatar
Matthias Clasen committed
279 280
	
	g_free (node->name);
281
	g_ir_node_free ((GIrNode *)field->type);
Matthias Clasen's avatar
Matthias Clasen committed
282 283 284
      }
      break;

285 286
    case G_IR_NODE_OBJECT:
    case G_IR_NODE_INTERFACE:
Matthias Clasen's avatar
Matthias Clasen committed
287
      {
288
	GIrNodeInterface *iface = (GIrNodeInterface *)node;
Matthias Clasen's avatar
Matthias Clasen committed
289 290
	
	g_free (node->name);
291 292
	g_free (iface->gtype_name);
	g_free (iface->gtype_init);
293

294 295

	g_free (iface->glib_type_struct);
Matthias Clasen's avatar
Matthias Clasen committed
296 297 298
	g_free (iface->parent);

	for (l = iface->interfaces; l; l = l->next)
299
	  g_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
300 301 302
	g_list_free (iface->interfaces);

	for (l = iface->members; l; l = l->next)
303
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
304 305 306 307 308
	g_list_free (iface->members);

      }
      break;
 
309
    case G_IR_NODE_VALUE:
Matthias Clasen's avatar
Matthias Clasen committed
310 311 312 313 314
      {
	g_free (node->name);
      }
      break;

315 316
    case G_IR_NODE_ENUM:
    case G_IR_NODE_FLAGS:
Matthias Clasen's avatar
Matthias Clasen committed
317
      {
318
	GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
Matthias Clasen's avatar
Matthias Clasen committed
319 320
	
	g_free (node->name);
321 322 323
	g_free (enum_->gtype_name);
	g_free (enum_->gtype_init);

Matthias Clasen's avatar
Matthias Clasen committed
324
	for (l = enum_->values; l; l = l->next)
325
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
326 327 328 329
	g_list_free (enum_->values);
      }
      break;

330
    case G_IR_NODE_BOXED:
Matthias Clasen's avatar
Matthias Clasen committed
331
      {
332
	GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
Matthias Clasen's avatar
Matthias Clasen committed
333 334
	
	g_free (node->name);
335 336
	g_free (boxed->gtype_name);
	g_free (boxed->gtype_init);
Matthias Clasen's avatar
Matthias Clasen committed
337 338

	for (l = boxed->members; l; l = l->next)
339
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
340 341 342 343
	g_list_free (boxed->members);
      }
      break;

344
    case G_IR_NODE_STRUCT:
Matthias Clasen's avatar
Matthias Clasen committed
345
      {
346
	GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
Matthias Clasen's avatar
Matthias Clasen committed
347 348

	g_free (node->name);
349 350 351
	g_free (struct_->gtype_name);
	g_free (struct_->gtype_init);

Matthias Clasen's avatar
Matthias Clasen committed
352
	for (l = struct_->members; l; l = l->next)
353
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
354 355 356 357
	g_list_free (struct_->members);
      }
      break;

358
    case G_IR_NODE_CONSTANT:
Matthias Clasen's avatar
Matthias Clasen committed
359
      {
360
	GIrNodeConstant *constant = (GIrNodeConstant *)node;
Matthias Clasen's avatar
Matthias Clasen committed
361 362 363
	
	g_free (node->name);
	g_free (constant->value);
364
	g_ir_node_free ((GIrNode *)constant->type);
Matthias Clasen's avatar
Matthias Clasen committed
365 366 367
      }
      break;

368
    case G_IR_NODE_ERROR_DOMAIN:
Matthias Clasen's avatar
Matthias Clasen committed
369
      {
370
	GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
Matthias Clasen's avatar
Matthias Clasen committed
371 372 373 374 375 376 377
	
	g_free (node->name);
	g_free (domain->getquark);
	g_free (domain->codes);
      }
      break;

378
    case G_IR_NODE_XREF:
Matthias Clasen's avatar
Matthias Clasen committed
379
      {
380
	GIrNodeXRef *xref = (GIrNodeXRef *)node;
Matthias Clasen's avatar
Matthias Clasen committed
381 382 383 384 385 386
	
	g_free (node->name);
	g_free (xref->namespace);
      }
      break;

387
    case G_IR_NODE_UNION:
Matthias Clasen's avatar
Matthias Clasen committed
388
      {
389
	GIrNodeUnion *union_ = (GIrNodeUnion *)node;
Matthias Clasen's avatar
Matthias Clasen committed
390 391 392 393 394
	
	g_free (node->name);
	g_free (union_->gtype_name);
	g_free (union_->gtype_init);

395
	g_ir_node_free ((GIrNode *)union_->discriminator_type);
Matthias Clasen's avatar
Matthias Clasen committed
396
	for (l = union_->members; l; l = l->next)
397
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
398
	for (l = union_->discriminators; l; l = l->next)
399
	  g_ir_node_free ((GIrNode *)l->data);
Matthias Clasen's avatar
Matthias Clasen committed
400 401 402
      }
      break;

Matthias Clasen's avatar
Matthias Clasen committed
403 404 405 406 407
    default:
      g_error ("Unhandled node type %d\n", node->type);
      break;
    } 

408 409
  g_hash_table_destroy (node->attributes);

Matthias Clasen's avatar
Matthias Clasen committed
410 411 412
  g_free (node);
}

413 414
/* returns the fixed size of the blob */
guint32
415
g_ir_node_get_size (GIrNode *node)
416 417 418 419 420 421
{
  GList *l;
  gint size, n;

  switch (node->type)
    {
422
    case G_IR_NODE_CALLBACK:
423
      size = sizeof (CallbackBlob);
424 425
      break;

426
    case G_IR_NODE_FUNCTION:
427
      size = sizeof (FunctionBlob);
428 429
      break;

430
    case G_IR_NODE_PARAM:
431 432
      /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
      size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
433 434
      break;

435
    case G_IR_NODE_TYPE:
436
      size = sizeof (SimpleTypeBlob);
437 438
      break;

439
    case G_IR_NODE_OBJECT:
440
      {
441
	GIrNodeInterface *iface = (GIrNodeInterface *)node;
442 443

	n = g_list_length (iface->interfaces);
444
	size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
445 446

	for (l = iface->members; l; l = l->next)
447
	  size += g_ir_node_get_size ((GIrNode *)l->data);
448 449 450
      }
      break;

451
    case G_IR_NODE_INTERFACE:
452
      {
453
	GIrNodeInterface *iface = (GIrNodeInterface *)node;
454 455

	n = g_list_length (iface->prerequisites);
456
	size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
457 458

	for (l = iface->members; l; l = l->next)
459
	  size += g_ir_node_get_size ((GIrNode *)l->data);
460 461 462
      }
      break;

463 464
    case G_IR_NODE_ENUM:
    case G_IR_NODE_FLAGS:
465
      {
466
	GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
467
	
468
	size = sizeof (EnumBlob);
469
	for (l = enum_->values; l; l = l->next)
470
	  size += g_ir_node_get_size ((GIrNode *)l->data);
471 472 473
      }
      break;

474
    case G_IR_NODE_VALUE:
475
      size = sizeof (ValueBlob);
476 477
      break;

478
    case G_IR_NODE_STRUCT:
479
      {
480
	GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
481

482
	size = sizeof (StructBlob);
483
	for (l = struct_->members; l; l = l->next)
484
	  size += g_ir_node_get_size ((GIrNode *)l->data);
485 486 487
      }
      break;

488
    case G_IR_NODE_BOXED:
489
      {
490
	GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
491

492
	size = sizeof (StructBlob);
493
	for (l = boxed->members; l; l = l->next)
494
	  size += g_ir_node_get_size ((GIrNode *)l->data);
495 496 497
      }
      break;

498
    case G_IR_NODE_PROPERTY:
499
      size = sizeof (PropertyBlob);
500 501
      break;

502
    case G_IR_NODE_SIGNAL:
503
      size = sizeof (SignalBlob);
504 505
      break;

506
    case G_IR_NODE_VFUNC:
507
      size = sizeof (VFuncBlob);
508 509
      break;

510
    case G_IR_NODE_FIELD:
511
      size = sizeof (FieldBlob);
512 513
      break;

514
    case G_IR_NODE_CONSTANT:
515
      size = sizeof (ConstantBlob);
516 517
      break;

518
    case G_IR_NODE_ERROR_DOMAIN:
519
      size = sizeof (ErrorDomainBlob);
520 521
      break;

522
    case G_IR_NODE_XREF:
523 524 525
      size = 0;
      break;

526
    case G_IR_NODE_UNION:
527
      {
528
	GIrNodeUnion *union_ = (GIrNodeUnion *)node;
529

530
	size = sizeof (UnionBlob);
531
	for (l = union_->members; l; l = l->next)
532
	  size += g_ir_node_get_size ((GIrNode *)l->data);
533
	for (l = union_->discriminators; l; l = l->next)
534
	  size += g_ir_node_get_size ((GIrNode *)l->data);
535 536 537 538
      }
      break;

    default: 
539 540
      g_error ("Unhandled node type '%s'\n",
	       g_ir_node_type_to_string (node->type));
541 542 543
      size = 0;
    }

544 545
  g_debug ("node %p type '%s' size %d", node,
	   g_ir_node_type_to_string (node->type), size);
546 547 548 549

  return size;
}

550 551 552 553 554 555 556 557 558 559 560 561
static void
add_attribute_size (gpointer key, gpointer value, gpointer data)
{
  const gchar *key_str = key;
  const gchar *value_str = value;
  gint *size_p = data;

  *size_p += sizeof (AttributeBlob);
  *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
  *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
}

562
/* returns the full size of the blob including variable-size parts */
563
static guint32
564 565
g_ir_node_get_full_size_internal (GIrNode *parent,
				  GIrNode *node)
566 567 568 569
{
  GList *l;
  gint size, n;

570 571
  if (node == NULL && parent != NULL)
    g_error ("Caught NULL node, parent=%s", parent->name);
572

573 574 575
  g_debug ("node %p type '%s'", node,
	   g_ir_node_type_to_string (node->type));

576 577
  switch (node->type)
    {
578
    case G_IR_NODE_CALLBACK:
579
      {
580
	GIrNodeFunction *function = (GIrNodeFunction *)node;
581
	size = sizeof (CallbackBlob);
582 583
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	for (l = function->parameters; l; l = l->next)
584 585 586 587
	  {
	    size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
	  }
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
588 589 590
      }
      break;

591
    case G_IR_NODE_FUNCTION:
592
      {
593
	GIrNodeFunction *function = (GIrNodeFunction *)node;
594
	size = sizeof (FunctionBlob);
595 596 597
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
	for (l = function->parameters; l; l = l->next)
598 599
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
600 601 602
      }
      break;

603
    case G_IR_NODE_PARAM:
604
      {
605
	GIrNodeParam *param = (GIrNodeParam *)node;
606
	
607 608
	/* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
	size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
609 610
	if (node->name)
	  size += ALIGN_VALUE (strlen (node->name) + 1, 4);
611
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);	
612 613 614
      }
      break;

615
    case G_IR_NODE_TYPE:
616
      {
617
	GIrNodeType *type = (GIrNodeType *)node;
618 619
        size = sizeof (SimpleTypeBlob);
        if (type->tag >= GI_TYPE_TAG_ARRAY)
620
	  {
621
	    g_debug ("node %p type tag '%s'", node,
622
		     g_type_tag_to_string (type->tag));
623

624 625
	    switch (type->tag)
	      {
626
	      case GI_TYPE_TAG_ARRAY:
627
		size = sizeof (ArrayTypeBlob);
628
		if (type->parameter_type1)
629
		  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
630
		break;
631
	      case GI_TYPE_TAG_INTERFACE:
632
		size += sizeof (InterfaceTypeBlob);
633
		break;
634 635
	      case GI_TYPE_TAG_GLIST:
	      case GI_TYPE_TAG_GSLIST:
636
		size += sizeof (ParamTypeBlob);
637
		if (type->parameter_type1)
638
		  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
639
		break;
640
	      case GI_TYPE_TAG_GHASH:
641
		size += sizeof (ParamTypeBlob) * 2;
642
		if (type->parameter_type1)
643
		  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
644
		if (type->parameter_type2)
645
		  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
646
		break;
647
	      case GI_TYPE_TAG_ERROR:
648 649 650 651 652 653 654 655
		{
		  gint n;
		  
		  if (type->errors)
		    n = g_strv_length (type->errors);
		  else
		    n = 0;

656
		  size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2);
657 658 659 660 661 662 663 664 665 666
		}
		break;
	      default:
		g_error ("Unknown type tag %d\n", type->tag);
		break;
	      }
	  }
      }
      break;

667
    case G_IR_NODE_OBJECT:
668
      {
669
	GIrNodeInterface *iface = (GIrNodeInterface *)node;
670 671

	n = g_list_length (iface->interfaces);
672
	size = sizeof(ObjectBlob);
673 674
	if (iface->parent)
	  size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
675 676
        if (iface->glib_type_struct)
          size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
677 678
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
679 680
	if (iface->gtype_init)
	  size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
681 682 683
	size += 2 * (n + (n % 2));

	for (l = iface->members; l; l = l->next)
684
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
685 686 687
      }
      break;

688
    case G_IR_NODE_INTERFACE:
689
      {
690
	GIrNodeInterface *iface = (GIrNodeInterface *)node;
691 692

	n = g_list_length (iface->prerequisites);
693
	size = sizeof (InterfaceBlob);
694 695 696 697 698 699
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
	size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
	size += 2 * (n + (n % 2));

	for (l = iface->members; l; l = l->next)
700
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
701 702 703
      }
      break;

704 705
    case G_IR_NODE_ENUM:
    case G_IR_NODE_FLAGS:
706
      {
707
	GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
708
	
709
	size = sizeof (EnumBlob);
710 711 712 713 714 715 716 717
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	if (enum_->gtype_name)
	  {
	    size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
	    size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
	  }

	for (l = enum_->values; l; l = l->next)
718
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);	
719 720 721
      }
      break;

722
    case G_IR_NODE_VALUE:
723
      {
724
	size = sizeof (ValueBlob);
725 726 727 728
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
      }
      break;

729
    case G_IR_NODE_STRUCT:
730
      {
731
	GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
732

733
	size = sizeof (StructBlob);
734
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
735 736 737 738
	if (struct_->gtype_name)
	  size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
	if (struct_->gtype_init)
	  size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
739
	for (l = struct_->members; l; l = l->next)
740
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
741 742 743
      }
      break;

744
    case G_IR_NODE_BOXED:
745
      {
746
	GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
747

748
	size = sizeof (StructBlob);
749 750 751 752 753 754 755
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	if (boxed->gtype_name)
	  {
	    size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
	    size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
	  }
	for (l = boxed->members; l; l = l->next)
756
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
757 758 759
      }
      break;

760
    case G_IR_NODE_PROPERTY:
761
      {
762
	GIrNodeProperty *prop = (GIrNodeProperty *)node;
763
	
764
	size = sizeof (PropertyBlob);
765
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
766
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type);	
767 768 769
      }
      break;

770
    case G_IR_NODE_SIGNAL:
771
      {
772
	GIrNodeSignal *signal = (GIrNodeSignal *)node;
773

774
	size = sizeof (SignalBlob);
775 776
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	for (l = signal->parameters; l; l = l->next)
777 778
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result);
779 780 781
      }
      break;

782
    case G_IR_NODE_VFUNC:
783
      {
784
	GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
785

786
	size = sizeof (VFuncBlob);
787 788
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	for (l = vfunc->parameters; l; l = l->next)
789 790
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result);
791 792 793
      }
      break;

794
    case G_IR_NODE_FIELD:
795
      {
796
	GIrNodeField *field = (GIrNodeField *)node;
797

798
	size = sizeof (FieldBlob);
799
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
800
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);	
801 802 803
      }
      break;

804
    case G_IR_NODE_CONSTANT:
805
      {
806
	GIrNodeConstant *constant = (GIrNodeConstant *)node;
807

808
	size = sizeof (ConstantBlob);
809 810 811
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	/* FIXME non-string values */
	size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
812
	size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type);	
813 814 815
      }
      break;

816
    case G_IR_NODE_ERROR_DOMAIN:
817
      {
818
	GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
819

820
	size = sizeof (ErrorDomainBlob);
821 822 823 824 825
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
      }
      break;

826
    case G_IR_NODE_XREF:
827
      {
828
	GIrNodeXRef *xref = (GIrNodeXRef *)node;
829 830 831 832 833 834 835
	
	size = 0;
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
	size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
      }
      break;

836
    case G_IR_NODE_UNION:
837
      {
838
	GIrNodeUnion *union_ = (GIrNodeUnion *)node;
839

840
	size = sizeof (UnionBlob);
841
	size += ALIGN_VALUE (strlen (node->name) + 1, 4);
842 843 844 845
	if (union_->gtype_name)
	  size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
	if (union_->gtype_init)
	  size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
846
	for (l = union_->members; l; l = l->next)
847
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
848
	for (l = union_->discriminators; l; l = l->next)
849
	  size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
850 851 852 853 854 855 856 857
      }
      break;

    default: 
      g_error ("Unknown type tag %d\n", node->type);
      size = 0;
    }

858 859 860 861 862
  g_debug ("node %s%s%s%p type '%s' full size %d",
	   node->name ? "'" : "",
	   node->name ? node->name : "",
	   node->name ? "' " : "",
	   node, g_ir_node_type_to_string (node->type), size);
863 864 865 866

  return size;
}

867 868 869 870 871 872
guint32
g_ir_node_get_full_size (GIrNode *node)
{
  return g_ir_node_get_full_size_internal (NULL, node);
}

Colin Walters's avatar