From b0884ff2484954f99ecded09234289d7f3ba6ce4 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Mon, 23 Apr 2012 16:15:25 +0200 Subject: [PATCH] fixed memleaks --- Ahuacatl/ast-codegen-js.c | 84 +++++++++++++++++++++++++++++++-------- Ahuacatl/ast-codegen-js.h | 1 + Ahuacatl/parser.c | 36 +++++++++++++++-- 3 files changed, 101 insertions(+), 20 deletions(-) diff --git a/Ahuacatl/ast-codegen-js.c b/Ahuacatl/ast-codegen-js.c index 7c5c5888d3..3791735e88 100644 --- a/Ahuacatl/ast-codegen-js.c +++ b/Ahuacatl/ast-codegen-js.c @@ -25,6 +25,8 @@ /// @author Copyright 2012, triagens GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// +#include + #include "Ahuacatl/ast-codegen-js.h" // ----------------------------------------------------------------------------- @@ -36,7 +38,21 @@ /// @{ //////////////////////////////////////////////////////////////////////////////// -static char* GetIndexedFunctionName (const size_t funcIndex) { +//////////////////////////////////////////////////////////////////////////////// +/// @brief register a function name for later disposal +//////////////////////////////////////////////////////////////////////////////// + +static bool RegisterString (TRI_aql_codegen_t* const generator, + const char* const name) { + assert(generator); + + TRI_PushBackVectorPointer(&generator->_strings, (char*) name); + + return true; +} + +static char* GetIndexedFunctionName (TRI_aql_codegen_t* const generator, + const size_t funcIndex) { char* numberString; char* functionName; @@ -45,7 +61,10 @@ static char* GetIndexedFunctionName (const size_t funcIndex) { return NULL; } - functionName = TRI_Concatenate2String("f", numberString); + functionName = TRI_Concatenate2String("f", numberString); + if (functionName) { + RegisterString(generator, functionName); + } TRI_Free(numberString); @@ -57,7 +76,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) { assert(generator); - functionName = GetIndexedFunctionName(++generator->_funcIndex); + functionName = GetIndexedFunctionName(generator, ++generator->_funcIndex); return functionName; } @@ -65,9 +84,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) { static void FreeScope (TRI_aql_codegen_scope_t* const scope) { assert(scope); - if (scope->_funcName) { - TRI_Free(scope->_funcName); - } + // note: scope->_funcName is freed globally if (scope->_buffer) { TRI_FreeStringBuffer(scope->_buffer); @@ -76,7 +93,9 @@ static void FreeScope (TRI_aql_codegen_scope_t* const scope) { TRI_Free(scope); } -static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const TRI_aql_scope_type_e type) { +static TRI_aql_codegen_scope_t* CreateScope (TRI_aql_codegen_t* const generator, + const char* const funcName, + const TRI_aql_scope_type_e type) { TRI_aql_codegen_scope_t* scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t)); if (!scope) { @@ -84,13 +103,19 @@ static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const T } scope->_funcName = TRI_DuplicateString(funcName); + if (!scope->_funcName) { + FreeScope(scope); + return NULL; + } + + RegisterString(generator, scope->_funcName); scope->_variablePrefix = NULL; scope->_indent = 0; scope->_forLoops = 0; scope->_type = type; scope->_buffer = TRI_CreateStringBuffer(); - if (!scope->_funcName || !scope->_buffer) { + if (!scope->_buffer) { FreeScope(scope); return NULL; } @@ -104,7 +129,7 @@ static bool StartScope (TRI_aql_codegen_t* const generator, const TRI_aql_scope_ assert(generator); assert(funcName); - scope = CreateScope(funcName, type); + scope = CreateScope(generator, funcName, type); if (!scope) { return false; @@ -236,7 +261,7 @@ static char* EndScope (TRI_aql_codegen_t* const generator) { assert(scope); - funcName = TRI_DuplicateString(scope->_funcName); + funcName = scope->_funcName; body = TRI_CreateStringBuffer(); if (!body) { @@ -638,7 +663,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator, AppendCode(generator, "("); GenerateCode(generator, ((TRI_aql_node_expand_t*) node)->_expanded); AppendCode(generator, ")"); - TRI_Free(funcName); break; } case AQL_NODE_ASSIGN: @@ -661,7 +685,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator, AppendCode(generator, funcName); AppendCode(generator, "($)"); - TRI_Free(funcName); break; } case AQL_NODE_FILTER: @@ -686,14 +709,27 @@ static void GenerateCode (TRI_aql_codegen_t* const generator, break; case AQL_NODE_LIMIT: { char* previousFunction; + char* value; AppendIndent(generator); AppendCode(generator, "result.push($);\n"); CloseForLoops(generator); AppendCode(generator, " result = AHUACATL_LIMIT(result, "); - AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset)); // todo: oom + + value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset); + if (!value) { + return; // todo: OOM + } + RegisterString(generator, value); + AppendCode(generator, value); AppendCode(generator, ", "); - AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count)); // todo: oom + + value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count); + if (!value) { + return; // todo: OOM + } + RegisterString(generator, value); + AppendCode(generator, value); AppendCode(generator, ");\n"); previousFunction = EndScope(generator); @@ -718,7 +754,7 @@ static void GenerateCode (TRI_aql_codegen_t* const generator, size_t i; size_t n; - previousFunction = TRI_DuplicateString(scope->_funcName); + previousFunction = scope->_funcName; // todo: OOM sortFuncName = GetNextFunctionName(generator); @@ -1005,13 +1041,15 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) { generator->_funcName = NULL; TRI_InitStringBuffer(&generator->_buffer); + + TRI_InitVectorPointer(&generator->_strings); TRI_InitVectorPointer(&generator->_scopes); if (!StartScope(generator, AQL_SCOPE_RESULT, GetNextFunctionName(generator))) { TRI_FreeCodegenAql(generator); return NULL; } - + return generator; } @@ -1020,11 +1058,23 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) { //////////////////////////////////////////////////////////////////////////////// void TRI_FreeCodegenAql (TRI_aql_codegen_t* const generator) { + size_t i; + assert(generator); TRI_DestroyStringBuffer(&generator->_buffer); TRI_DestroyVectorPointer(&generator->_scopes); + // free strings + i = generator->_strings._length; + while (i--) { + void* string = generator->_strings._buffer[i]; + if (string) { + TRI_Free(string); + } + } + TRI_DestroyVectorPointer(&generator->_strings); + TRI_Free(generator); } @@ -1065,7 +1115,7 @@ char* TRI_GenerateCodeAql (const void* const data) { TRI_AppendStringStringBuffer(&generator->_buffer, "})();\n"); code = TRI_DuplicateString(generator->_buffer._buffer); - printf("CODE IS:\n%s\n\n",code); + LOG_TRACE("generated code:\n%s\n",code); } TRI_FreeCodegenAql(generator); diff --git a/Ahuacatl/ast-codegen-js.h b/Ahuacatl/ast-codegen-js.h index a8cbcdc242..9f2cb44f9b 100644 --- a/Ahuacatl/ast-codegen-js.h +++ b/Ahuacatl/ast-codegen-js.h @@ -73,6 +73,7 @@ typedef struct TRI_aql_codegen_s { size_t _funcIndex; bool _error; char* _funcName; + TRI_vector_pointer_t _strings; } TRI_aql_codegen_t; diff --git a/Ahuacatl/parser.c b/Ahuacatl/parser.c index 63557419dd..0cbcad996e 100644 --- a/Ahuacatl/parser.c +++ b/Ahuacatl/parser.c @@ -143,27 +143,57 @@ TRI_aql_parse_context_t* TRI_CreateParseContextAql (const char* const query) { //////////////////////////////////////////////////////////////////////////////// void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) { + size_t i; + assert(context); + // free all remaining scopes while (context->_scopes._length) { TRI_EndScopeParseContextAql(context); } - - // TODO: Free nodes TRI_DestroyVectorPointer(&context->_scopes); - TRI_DestroyVectorPointer(&context->_nodes); + + // free all strings registered + i = context->_strings._length; + while (i--) { + void* string = context->_strings._buffer[i]; + + if (string) { + TRI_Free(context->_strings._buffer[i]); + } + } TRI_DestroyVectorPointer(&context->_strings); + + // free all nodes registered + i = context->_nodes._length; + while (i--) { + TRI_aql_node_t* node = (TRI_aql_node_t*) context->_nodes._buffer[i]; + if (node) { + if (node->free) { + // call node's specific free function + node->free(node); + } + // free node itself + TRI_Free(node); + } + } + TRI_DestroyVectorPointer(&context->_nodes); + + // free the stack TRI_DestroyVectorPointer(&context->_stack); + // free query string if (context->_query) { TRI_Free(context->_query); } + // free lexer if (context->_parser) { Ahuacatllex_destroy(context->_parser->_scanner); TRI_Free(context->_parser); } + // free error struct TRI_DestroyErrorAql(&context->_error); TRI_Free(context);