tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] libtcc API v.s. global state v.s. tcc state


From: egodust
Subject: Re: [Tinycc-devel] libtcc API v.s. global state v.s. tcc state
Date: Sun, 20 Apr 2008 21:26:00 +0100

Hey,

On Sun, Apr 20, 2008 at 8:50 PM, grischka <address@hidden> wrote:
> From: "egodust":
>
> > 1. tcc_new() MUST be matched by a tcc_delete() that share the same
>  > sections, i.e. no mixing of different states, only ONE state is
>  > allowed to exist at a time because of global copies.
>
>  No, that does not follow necessarily. It only means that
>  only one state can have global copies. But there can be
>  other states too, just not with global copies.

Yes, but then there is a memory leak!, tcc_new() overwrites globals
with section data that tcc_delete() frees, it can only free the 'last
known' section, i.e.

tcc=tcc_new()
tcc_delete(tcc) // frees global copy too

tcc=tcc_new()
tcc=tcc_new() // bad, overwritten global section pointers
tcc_delete(tcc); // frees last global section
>
>
>  > tcc_delete() does:
>  >
>  >  free_section(symtab_section->hash);
>
>  You can make free_section delete the hash link automatically.
>  Then this is not needed.

Sure :) but these modifications still need to take place...
>
>
>  > So because of globals, tcc_new() and tcc_delete() must MATCH, you
>  > can't call tcc_delete() afterwards, because tcc_new() overrides
>  > globals.
>
>  No, that is not how it is. True, tcc_new() overrides globals, but
>  that only means that you cannot do compilation with an old state
>  anymore.  But you still can run the code in it.  It's not perfect,
>  but it is equal to your solution.  I mean, it *IS* your solution,
>  just that TCCBinary is TCCState actually.

It isn't equal, since my version stops the memory leaks?
>
>
>  > Sure, but libtcc passes around global data that is shared with ONE
>  > state. I only wanted the binary to stay in memory, if you don't like
>  > the APIs (i.e. the extra free), feel free to suggest something else :)
>  >
>  > I just didn't want to complicate the design.
>
>  But you did exactly that by adding extra functions to the libtcc
>  interface ;)
>
>  Well, I need to suggest something.  So, maybe I'd move the bits in
>  tcc_delete, that mess with globals, out from tcc_delete into another
>  function.  Then that function (name it "tcc_cleanup") can be called
>  from tcc_new instead.  How is this?

I would rather the library dealt with its allocations itself, rather
than the client code keeping track for it?
>
>  To make it all balanced you can have a state counter.
>
>  tcc_new()
>  {
>    if (state_count++)
>         tcc_cleanup();
>    ...
>
>  tcc_delete()
>  {
>     if (0 == --state_count)
>         tcc_cleanup();
>     ...
>
>

How about the following design instead:

// modify structure
struct TCCState
{
   int just_free_sections; // defaults to 0
}

// copies generated binary image from tcc into a new state
TCCState * tcc_export_binary(TCCState * tcc)
{
   TCCState * s1 = malloc(...)
   s1->just_free_sections++;
   // move sections from 'tcc' into new 's1'
   s1->nb_sections = tcc->nb_sections;
   // make 'tcc' forget its sections
   s1->sections = tcc->sections;
   tcc->sections=NULL;
   tcc->nb_sections=0;
   return s1;
}

// modify tcc_delete to free sections
void tcc_delete(TCCState *s1)
{
   if ( s1->just_free_sections )
   {
      // free section(s) in s1
      free(s1);
      return;
   }
   // normal processing
}

This method leaves only one extra API call in libtcc, i.e. tcc_export_binary

>
>  --- grischka
>

It would be great if tcc_new() allocations to global copies did not
matter, but there seems to be lots of places (esp when setjmp() is
used) that leave those global copies around, I understand what you are
saying: Do not use tcc_delete() til you want to free the sections that
have been created, but.. there are problems when tcc_new() is called
again :/

Regards,
Sam




reply via email to

[Prev in Thread] Current Thread [Next in Thread]