From 12331d66f5c9cb657e3d34aaaf0f3dd7a0afff08 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 9 Jun 2014 13:02:39 -0700 Subject: [PATCH] Fix memory leaks --- include/tree_sitter/parser.h | 2 +- include/tree_sitter/parser/lr_parser.h | 1 + spec/runtime/helpers/read_test_entries.cc | 2 ++ spec/runtime/helpers/spy_reader.cc | 7 +------ spec/runtime/language_specs.cc | 14 +++++++------- src/runtime/document.c | 4 ++++ src/runtime/lr_parser.c | 8 ++++++++ 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index f7c0a1f5..2b6478bb 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -75,7 +75,7 @@ static const ts_tree * ts_parse(void *data, ts_input input, ts_input_edit *edit) ts_parser constructor_name() { \ return (ts_parser) { \ .parse_fn = ts_parse, \ - .free_fn = NULL, \ + .free_fn = ts_lr_parser_free, \ .symbol_names = ts_symbol_names, \ .data = ts_lr_parser_make( \ SYMBOL_COUNT, \ diff --git a/include/tree_sitter/parser/lr_parser.h b/include/tree_sitter/parser/lr_parser.h index cc83c7c0..70445cd1 100644 --- a/include/tree_sitter/parser/lr_parser.h +++ b/include/tree_sitter/parser/lr_parser.h @@ -56,6 +56,7 @@ ts_lr_parser * ts_lr_parser_make(size_t symbol_count, ts_tree * (* lex_fn)(ts_lexer *, ts_state_id), const int *hidden_symbol_flags, const int *ubiquitous_symbol_flags); +void ts_lr_parser_free(void *data); void ts_lr_parser_initialize(ts_lr_parser *parser, ts_input input, ts_input_edit *edit); ts_tree * ts_lr_parser_parse(ts_lr_parser *parser, const char **symbol_names); diff --git a/spec/runtime/helpers/read_test_entries.cc b/spec/runtime/helpers/read_test_entries.cc index 663ebfd9..3a5181c6 100644 --- a/spec/runtime/helpers/read_test_entries.cc +++ b/spec/runtime/helpers/read_test_entries.cc @@ -89,6 +89,8 @@ static vector list_directory(string dir_name) { if (name != "." && name != "..") result.push_back(dir_name + "/" + name); } + + closedir(dir); return result; } diff --git a/spec/runtime/helpers/spy_reader.cc b/spec/runtime/helpers/spy_reader.cc index 27f0201a..df79c6c3 100644 --- a/spec/runtime/helpers/spy_reader.cc +++ b/spec/runtime/helpers/spy_reader.cc @@ -21,11 +21,6 @@ static int spy_seek(void *data, size_t position) { return 0; } -static void spy_release(void *data) { - SpyReader *reader = static_cast(data); - delete reader; -} - SpyReader::SpyReader(string content, size_t chunk_size) : content(content), position(0), @@ -34,5 +29,5 @@ SpyReader::SpyReader(string content, size_t chunk_size) : this, spy_read, spy_seek, - spy_release, + nullptr, }) {} diff --git a/spec/runtime/language_specs.cc b/spec/runtime/language_specs.cc index 9c6a08fa..582ce339 100644 --- a/spec/runtime/language_specs.cc +++ b/spec/runtime/language_specs.cc @@ -19,12 +19,12 @@ describe("Languages", [&]() { ts_document_free(doc); }); - auto run_tests_for_language = [&](string language, ts_parser parser) { + auto run_tests_for_language = [&](string language, ts_parser (parser_constructor)()) { describe(language.c_str(), [&]() { before_each([&]() { - ts_document_set_parser(doc, parser); + ts_document_set_parser(doc, parser_constructor()); }); - + for (auto &entry : test_entries_for_language(language)) { it(entry.description.c_str(), [&]() { ts_document_set_input_string(doc, entry.input.c_str()); @@ -34,10 +34,10 @@ describe("Languages", [&]() { }); }; - run_tests_for_language("json", ts_parser_json()); - run_tests_for_language("arithmetic", ts_parser_arithmetic()); - run_tests_for_language("javascript", ts_parser_javascript()); - run_tests_for_language("golang", ts_parser_golang()); + run_tests_for_language("json", ts_parser_json); + run_tests_for_language("arithmetic", ts_parser_arithmetic); + run_tests_for_language("javascript", ts_parser_javascript); + run_tests_for_language("golang", ts_parser_golang); }); END_TEST \ No newline at end of file diff --git a/src/runtime/document.c b/src/runtime/document.c index 4ab6e477..e50fb6cf 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -13,6 +13,10 @@ ts_document * ts_document_make() { } void ts_document_free(ts_document *document) { + if (document->parser.free_fn) + document->parser.free_fn(document->parser.data); + if (document->input.release_fn) + document->input.release_fn(document->input.data); free(document); } diff --git a/src/runtime/lr_parser.c b/src/runtime/lr_parser.c index 9c71d87a..0094af33 100644 --- a/src/runtime/lr_parser.c +++ b/src/runtime/lr_parser.c @@ -176,6 +176,14 @@ ts_lr_parser * ts_lr_parser_make(size_t symbol_count, return result; } +void ts_lr_parser_free(void *data) { + ts_lr_parser *parser = (ts_lr_parser *)data; + if (parser->lookahead) ts_tree_release(parser->lookahead); + if (parser->next_lookahead) ts_tree_release(parser->next_lookahead); + ts_stack_delete(&parser->stack); + free(parser); +} + void ts_lr_parser_initialize(ts_lr_parser *parser, ts_input input, ts_input_edit *edit) { if (!edit) ts_stack_shrink(&parser->stack, 0); parser->lookahead = NULL;