Skip to content

Commit

Permalink
kernel: fix mem leaks
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-mitchell committed Sep 12, 2023
1 parent c4fb7e2 commit 3162f5b
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 25 deletions.
8 changes: 3 additions & 5 deletions etc/tst-local-vars.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""
TODO
This simple script adds the local variables used in a GAP tst file to the top
of the file.
"""
import os
import re
Expand All @@ -24,10 +25,7 @@ def main():
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = ", ".join(sorted([*{*lvars}]))
lvars = [
x if x[-1] != "," else x[:-1]
for x in textwrap.wrap(lvars, width=72)
]
lvars = [x if x[-1] != "," else x[:-1] for x in textwrap.wrap(lvars, width=72)]
lvars = [""] + ["#@local " + x for x in lvars]
lines = lines.split("\n")
pos = next(i for i in range(len(lines)) if "START_TEST" in lines[i])
Expand Down
50 changes: 50 additions & 0 deletions etc/tst-unbind-local-vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""
This simple script adds the "Unbind" statements to the end of GAP tst file of
the file.
"""
import os
import re
import sys
import textwrap

import yaml
from bs4 import BeautifulSoup


def main():
if sys.version_info[0] < 3:
raise Exception("Python 3 is required")
args = sys.argv[1:]
pattern1 = re.compile(r"(\w+)\s*:=")
pattern2 = re.compile(r"for (\w+) in")
for fname in args:
lvars = []
with open(fname, "r") as f:
lines = f.read()
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = sorted([*{*lvars}])
lvars = [
"# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py"
] + [f"gap> Unbind({lvar});" for lvar in lvars]
lvars.append("")
lines = lines.split("\n")
pos1 = next(i for i in range(len(lines)) if "STOP_TEST" in lines[i]) - 1
try:
pos0 = next(
i
for i in range(len(lines))
if "etc/tst-unbind-local-vars.py" in lines[i]
)
except StopIteration:
pos0 = pos1
lines = lines[:pos0] + lvars + lines[pos1:]
lines = "\n".join(lines)
with open(fname, "w") as f:
print(f"Writing local variables to {fname}...")
f.write(lines)


if __name__ == "__main__":
main()
11 changes: 7 additions & 4 deletions gapbind14/include/gapbind14/gapbind14.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ namespace gapbind14 {
: SubtypeBase(nm, sbtyp) {}

void free(Obj o) override {
static_assert(IsGapBind14Type<T>::value,
"template parameter T must satisfy IsGapbind14Type<T>");
GAPBIND14_ASSERT(obj_subtype(o) == module().subtype<T>());
delete detail::obj_cpp_ptr<T>(o);
}
};
Expand Down Expand Up @@ -214,12 +217,12 @@ namespace gapbind14 {
_subtypes(),
_type_to_subtype() {}

Module(Module const&) = delete;
Module(Module&&) = delete;
Module(Module const&) = delete;
Module(Module&&) = delete;
Module& operator=(Module const&) = delete;
Module& operator=(Module&&) = delete;
Module& operator=(Module&&) = delete;

~Module() = default;
~Module();

void clear();

Expand Down
12 changes: 8 additions & 4 deletions gapbind14/include/gapbind14/to_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ namespace gapbind14 {

std::string operator()(Obj o) const {
if (TNUM_OBJ(o) != T_STRING) {
ErrorQuit("expected string, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected string, found ")
+ TNAM_OBJ(o));
}
return std::string(CSTR_STRING(o), GET_LEN_STRING(o));
}
Expand All @@ -106,7 +107,8 @@ namespace gapbind14 {

Int operator()(Obj o) const {
if (TNUM_OBJ(o) != T_INT) {
ErrorQuit("expected int, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected int, found ")
+ TNAM_OBJ(o));
}
return INT_INTOBJ(o);
}
Expand All @@ -123,7 +125,8 @@ namespace gapbind14 {

bool operator()(Obj o) const {
if (TNUM_OBJ(o) != T_BOOL) {
ErrorQuit("expected bool, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected bool, found ")
+ TNAM_OBJ(o));
}
return o == True ? true : false;
}
Expand All @@ -140,7 +143,8 @@ namespace gapbind14 {

std::vector<T> operator()(Obj o) const {
if (!IS_LIST(o)) {
ErrorQuit("expected list, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected list, found ")
+ TNAM_OBJ(o));
}

size_t const N = LEN_LIST(o);
Expand Down
34 changes: 28 additions & 6 deletions gapbind14/src/gapbind14.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

#include "gapbind14/gapbind14.hpp"

#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr
//
#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr

#include <unordered_set> // for unordered_set, unordered_set<>::iterator

#include "gapbind14/gap_include.hpp" // for Obj etc
Expand Down Expand Up @@ -93,10 +93,32 @@ namespace gapbind14 {

// Module implementations

Module::~Module() {
clear();
for (auto *subtype : _subtypes) {
delete subtype;
}
}

void Module::clear() {
for (auto &func : _funcs) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
_funcs.clear();
for (auto &funcs : _mem_funcs) {
funcs.clear();

for (auto &vec : _mem_funcs) {
for (auto &func : vec) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
vec.clear();
}
}

Expand Down Expand Up @@ -266,7 +288,7 @@ namespace gapbind14 {
first_call = false;
InitGVarFuncsFromTable(GVarFuncs);
}
auto & m = module();
auto &m = module();
StructGVarFunc const *tab = m.funcs();

// init functions from m in the record named name
Expand Down
45 changes: 45 additions & 0 deletions tst/standard/attributes/homomorph.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,51 @@ gap> hom2 := SemigroupHomomorphismByImages(S, S, GeneratorsOfSemigroup(S),
gap> hom1 = hom2;
false
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceHomoCheck);
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(F);
gap> Unbind(J);
gap> Unbind(K);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(U);
gap> Unbind(V);
gap> Unbind(acting);
gap> Unbind(cong);
gap> Unbind(congs);
gap> Unbind(g);
gap> Unbind(gens);
gap> Unbind(gens1);
gap> Unbind(gens2);
gap> Unbind(gens3);
gap> Unbind(gensS);
gap> Unbind(gensT);
gap> Unbind(gensU);
gap> Unbind(gensV);
gap> Unbind(h);
gap> Unbind(hom);
gap> Unbind(hom1);
gap> Unbind(hom1bf);
gap> Unbind(hom1bfbi);
gap> Unbind(hom2);
gap> Unbind(hom3);
gap> Unbind(images);
gap> Unbind(images1);
gap> Unbind(images2);
gap> Unbind(images3);
gap> Unbind(imgs);
gap> Unbind(imgs2);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(j);
gap> Unbind(map);
gap> Unbind(relations);
gap> Unbind(x);
gap> Unbind(y);
gap> Unbind(z);
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/attributes/homomorph.tst");
24 changes: 19 additions & 5 deletions tst/standard/semigroups/semifp.tst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
##
#############################################################################
##

## We don't use local variables in this test file because it doesn't play nice
## with AssignGeneratorVariables, which is used repeatedly here.

gap> START_TEST("Semigroups package: standard/semigroups/semifp.tst");
gap> LoadPackage("semigroups", false);;

Expand Down Expand Up @@ -2666,23 +2670,33 @@ true
gap> IsSubsemigroupOfFpMonoid(Range(map));
true
# SEMIGROUPS_UnbindVariables
gap> Unbind(a);
gap> Unbind(b);
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(f);
gap> Unbind(F);
gap> Unbind(G);
gap> Unbind(LoopIterator);
gap> Unbind(Noop);
gap> Unbind(R);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(TestEnumerator);
gap> Unbind(TestIterator);
gap> Unbind(a);
gap> Unbind(b);
gap> Unbind(f);
gap> Unbind(factorizable);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(len);
gap> Unbind(map);
gap> Unbind(rels);
gap> Unbind(s);
gap> Unbind(tst);
gap> Unbind(valid);
gap> Unbind(w);
gap> Unbind(x);
gap> Unbind(y);
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/semigroups/semifp.tst");
3 changes: 2 additions & 1 deletion tst/standard/tools/display.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,8 @@ gap> TikzRightCayleyDigraph(S);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `TikzString' on 1 arguments

# SEMIGROUPS_UnbindVariables
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(S);
gap> Unbind(x);
gap> Unbind(y);

Expand Down

0 comments on commit 3162f5b

Please sign in to comment.