All allocations are now cleaned up neatly on exit. This is probably unnecessary given that we run our own heap but gives confidence that there are no internal memory leaks.

git-svn-id: http://picoc.googlecode.com/svn/trunk@199 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-11 23:49:10 +00:00
parent c403ddcd04
commit 48a6472c68
8 changed files with 78 additions and 3 deletions

1
TODO
View file

@ -22,7 +22,6 @@ Improvements:
* periodic heap cleanup * periodic heap cleanup
* octal/hex character constants * octal/hex character constants
* see if we can use ParserCopyPos() in other places rather than copying everything * see if we can use ParserCopyPos() in other places rather than copying everything
* do deallocation for 03_structs, 07_function, 10_pointer, 12_hashdefine, 15_recursion and 18_include called from wrong directory
Need test/debug: Need test/debug:
* all break/continue variations * all break/continue variations

7
lex.c
View file

@ -87,6 +87,12 @@ void LexInit()
ReservedWords[Count].SharedWord = TableStrRegister(ReservedWords[Count].Word); ReservedWords[Count].SharedWord = TableStrRegister(ReservedWords[Count].Word);
} }
/* deallocate */
void LexCleanup()
{
LexInteractiveClear(NULL);
}
/* check if a word is a reserved word - used while scanning */ /* check if a word is a reserved word - used while scanning */
enum LexToken LexCheckReservedWord(const char *Word) enum LexToken LexCheckReservedWord(const char *Word)
{ {
@ -661,6 +667,7 @@ void LexInteractiveClear(struct ParseState *Parser)
InteractiveHead = NextLine; InteractiveHead = NextLine;
} }
if (Parser != NULL)
Parser->Pos = NULL; Parser->Pos = NULL;
InteractiveTail = NULL; InteractiveTail = NULL;
} }

16
parse.c
View file

@ -1,5 +1,15 @@
#include "picoc.h" #include "picoc.h"
/* a chunk of heap-allocated tokens we should cleanup when we're done */
static void *CleanupTokens = NULL;
/* deallocate any memory */
void ParseCleanup()
{
if (CleanupTokens != NULL)
HeapFree(CleanupTokens);
}
/* parse a statement, but only run it if Condition is TRUE */ /* parse a statement, but only run it if Condition is TRUE */
int ParseStatementMaybeRun(struct ParseState *Parser, int Condition) int ParseStatementMaybeRun(struct ParseState *Parser, int Condition)
{ {
@ -472,7 +482,11 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
{ {
struct ParseState Parser; struct ParseState Parser;
void *OldCleanupTokens = CleanupTokens;
void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL); void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL);
if (OldCleanupTokens == NULL)
CleanupTokens = Tokens;
LexInitParser(&Parser, Tokens, FileName, 1, RunIt); LexInitParser(&Parser, Tokens, FileName, 1, RunIt);
while (ParseStatement(&Parser)) while (ParseStatement(&Parser))
@ -482,6 +496,8 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
ProgramFail(&Parser, "parse error"); ProgramFail(&Parser, "parse error");
HeapFree(Tokens); HeapFree(Tokens);
if (OldCleanupTokens == NULL)
CleanupTokens = NULL;
} }
/* parse interactively */ /* parse interactively */

View file

@ -16,6 +16,9 @@ void Initialise()
/* free memory */ /* free memory */
void Cleanup() void Cleanup()
{ {
PlatformCleanup();
ParseCleanup();
LexCleanup();
VariableCleanup(); VariableCleanup();
TypeCleanup(); TypeCleanup();
TableStrFree(); TableStrFree();

View file

@ -255,7 +255,8 @@ char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen);
void TableStrFree(); void TableStrFree();
/* lex.c */ /* lex.c */
void LexInit(void); void LexInit();
void LexCleanup();
void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen); void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen);
void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line, int RunIt); void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line, int RunIt);
enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos);
@ -270,6 +271,7 @@ int ParseStatement(struct ParseState *Parser);
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsProtoType); struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsProtoType);
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt); void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt);
void ParseInteractive(); void ParseInteractive();
void ParseCleanup();
/* expression.c */ /* expression.c */
int ExpressionParse(struct ParseState *Parser, struct Value **Result); int ExpressionParse(struct ParseState *Parser, struct Value **Result);
@ -298,6 +300,7 @@ void HeapFree(void *Mem);
/* variable.c */ /* variable.c */
void VariableInit(); void VariableInit();
void VariableCleanup(); void VariableCleanup();
void VariableTableCleanup(struct Table *HashTable);
void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap); void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap);
void VariableStackPop(struct ParseState *Parser, struct Value *Var); void VariableStackPop(struct ParseState *Parser, struct Value *Var);
struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap); struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap);
@ -323,6 +326,7 @@ void PrintFP(double Num, CharWriter *PutCh);
/* platform_support.c */ /* platform_support.c */
void ProgramFail(struct ParseState *Parser, const char *Message, ...); void ProgramFail(struct ParseState *Parser, const char *Message, ...);
void LexFail(struct LexState *Lexer, const char *Message, ...); void LexFail(struct LexState *Lexer, const char *Message, ...);
void PlatformCleanup();
void PlatformScanFile(const char *FileName); void PlatformScanFile(const char *FileName);
char *PlatformGetLine(char *Buf, int MaxLen); char *PlatformGetLine(char *Buf, int MaxLen);
void PlatformPutc(unsigned char OutCh); void PlatformPutc(unsigned char OutCh);

View file

@ -1,6 +1,16 @@
#include "picoc.h" #include "picoc.h"
#ifdef UNIX_HOST #ifdef UNIX_HOST
/* a source file we need to clean up */
static char *CleanupText = NULL;
/* deallocate any storage */
void PlatformCleanup()
{
if (CleanupText != NULL)
HeapFree(CleanupText);
}
/* get a line of interactive input */ /* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen) char *PlatformGetLine(char *Buf, int MaxLen)
{ {
@ -47,8 +57,15 @@ char *PlatformReadFile(const char *FileName)
void PlatformScanFile(const char *FileName) void PlatformScanFile(const char *FileName)
{ {
char *SourceStr = PlatformReadFile(FileName); char *SourceStr = PlatformReadFile(FileName);
char *OrigCleanupText = CleanupText;
if (CleanupText == NULL)
CleanupText = SourceStr;
Parse(FileName, SourceStr, strlen(SourceStr), TRUE); Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
free(SourceStr); free(SourceStr);
if (OrigCleanupText == NULL)
CleanupText = NULL;
} }
/* mark where to end the program for platforms which require this */ /* mark where to end the program for platforms which require this */
@ -66,6 +83,12 @@ void PlatformExit()
#endif #endif
#ifdef SURVEYOR_HOST #ifdef SURVEYOR_HOST
/* deallocate any storage */
void PlatformCleanup()
{
}
/* get a line of interactive input */ /* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen) char *PlatformGetLine(char *Buf, int MaxLen)
{ {

11
type.c
View file

@ -122,13 +122,24 @@ void TypeCleanupNode(struct ValueType *Typ)
struct ValueType *SubType; struct ValueType *SubType;
struct ValueType *NextSubType; struct ValueType *NextSubType;
/* clean up and free all the sub-nodes */
for (SubType = Typ->DerivedTypeList; SubType != NULL; SubType = NextSubType) for (SubType = Typ->DerivedTypeList; SubType != NULL; SubType = NextSubType)
{ {
NextSubType = SubType->Next; NextSubType = SubType->Next;
TypeCleanupNode(SubType); TypeCleanupNode(SubType);
if (SubType->OnHeap) if (SubType->OnHeap)
{
/* if it's a struct or union deallocate all the member values */
if (SubType->Members != NULL)
{
VariableTableCleanup(SubType->Members);
HeapFree(SubType->Members);
}
/* free this node */
HeapFree(SubType); HeapFree(SubType);
} }
}
} }
void TypeCleanup() void TypeCleanup()

View file

@ -35,8 +35,20 @@ void VariableTableCleanup(struct Table *HashTable)
NextEntry = Entry->Next; NextEntry = Entry->Next;
Val = Entry->p.v.Val; Val = Entry->p.v.Val;
if (Val->ValOnHeap) if (Val->ValOnHeap)
HeapFree(Val); {
/* free function bodies */
if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL)
HeapFree((void *)Val->Val->FuncDef.Body.Pos);
/* free macro bodies */
if (Val->Typ == &MacroType)
HeapFree((void *)Val->Val->Parser.Pos);
/* free the value */
HeapFree(Val);
}
/* free the hash table entry */
HeapFree(Entry); HeapFree(Entry);
} }
} }