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: grischka
Subject: Re: [Tinycc-devel] libtcc API v.s. global state v.s. tcc state
Date: Mon, 21 Apr 2008 00:55:57 +0200

From: "egodust":

> 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.

As far as I can see all section data can be reached from the
TCCState itself. For example "symtab_section" is in the section
array (s->sections) too. So we can also reach it's hash link.
So even if tcc_new overwrites the global copies, we can still
free all section data when we free the state.

However there is other stuff that is neither section data nor part
of the state, like the '#define' tokens (hence free_defines(NULL))
and the symbol tokens (hence tcc_free(table_ident[i])), and maybe
some other.

So we need to free this, but it can happen independantly from
deleting the state.

(Yes, I know, this means modifications need to take place ;)

> >  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?

Shure, it's all transparent to the user.

> 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

Progress ;) But I still think we don't need this.

> 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 :/

There may be problems (and probably are, esp. after error/setjmp()).
Anyway, I think it doesn't make sense to speculate too much.

What we need first of all is some test code. Kind of "multistate_ 
libtcc_test.c". I mean it doesn't make sense if we figure out
something and then cannot test it.

Anyone by any chance already has that? Or could write it?

Then we fix the crashes. Then we fix the memory leaks. Then
we make the code look nice ;)

--- grischka





reply via email to

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