[Top][All Lists]
[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