mkvsynth/mkvsynth — pull request #22 by lukechampine (2014-04-01 01:48:35+00:00)
Title: Memory management

This change finally addresses delbrot's memory leaking problems, fixing #6. The main culprits were unfreed environments; delbrot creates a new local environment when it handles a user-defined function call, and these were not being freed after exiting the function. Function arguments were also not being freed after use. Leaks relating to user-defined functions are the most important to plug, because recursive functions can eat lots of memory very quickly.

I'm happy to announce that user-defined functions are now completely leak-free. I'll let the results speak for themselves. Run the following code under the current build:
```
function fib(num a) {
if (a < 2)
return 1;
else
return fib (a-1) + fib (a-2);
}
fib 30 -> print;
```
On my machine, this leaks nearly 4GB of RAM. After memory management, it leaks nothing; `./mkvsynth` consumes under 1k of RAM no matter what Fibonacci number you calculate.

Global statements are still a bit leaky, but it's on the order of a few bytes per statement. These leaks have proved much more difficult to eradicate. The good news is that you would have to write many thousands of lines of scripting code before encountering any memory issues.

I tried writing a function to `import` a lengthy script file a bunch of times, but even that was thwarted:
```
function import_n(num n) {
if (n <= 0)
return;
import long_script_file;
import_n (n-1);
}
import_n 100;
```
It turns out that if you try to recursively import a script in this manner, flex will see that `long_script_file` is already on the import stack and throw a "circular reference" error. While technically a bug, I think this behavior should probably stay. :)

Internally, most instances of `ASTnode*` and `Value*` have been replaced with `ASTnode` and `Value`. This means there's much less heap memory to keep track of; just about everything is allocated on the stack and freed when it goes out of scope. As a result, functions now return a `Value` instead of a `Value*`. This is (almost certainly) the last time I'll break the spec, I swear.