Hey, On Sun, Apr 20, 2008 at 8:50 PM, grischka <[EMAIL PROTECTED]> 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 _______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/tinycc-devel