trying not to leak memory

This commit is contained in:
FelixBrendel
2019-10-30 00:47:52 +01:00
parent 814cceaf3d
commit a790a38655
22 changed files with 204 additions and 78 deletions
+25 -13
View File
@@ -69,35 +69,47 @@ proc built_in_load(String* file_name) -> Lisp_Object* {
}
create_generic_error("The file to load '%s' was not found in the load path.",
Memory::get_c_str(file_name));
return nullptr;
}
}
Lisp_Object* result = Memory::nil;
Array_List<Lisp_Object*> program;
Array_List<Lisp_Object*>* program;
try program = Parser::parse_program(Memory::create_string(fullpath), file_content);
for (int i = 0; i < program.next_index; ++i) {
try result = eval_expr(program.data[i]);
for (int i = 0; i < program->next_index; ++i) {
try result = eval_expr(program->data[i]);
}
delete program;
return result;
}
proc built_in_import(String* file_name) -> Lisp_Object* {
// create new empty environment
Environment* new_env;
try new_env = Memory::create_child_environment(get_root_environment());
new_env = Memory::file_to_env_map.get_object(Memory::get_c_str(file_name));
if (!new_env) {
// create new empty environment
try new_env = Memory::create_child_environment(get_root_environment());
// TODO(Felix): check absoulute paths in the map, not just
// relative ones
Memory::file_to_env_map.set_object(Memory::get_c_str(file_name), new_env);
push_environment(new_env);
defer {
pop_environment();
};
Lisp_Object* res;
try res = built_in_load(file_name);
}
get_current_environment()->parents.append(new_env);
push_environment(new_env);
defer {
pop_environment();
};
Lisp_Object* res = built_in_load(file_name);
return res;
return Memory::nil;
}
proc load_built_ins_into_environment() -> void {
+21
View File
@@ -128,3 +128,24 @@
#define in_caller_env fluid_let( \
Globals::Current_Execution::envi_stack.next_index, \
Globals::Current_Execution::envi_stack.next_index-1)
/*
* iterate over lisp vectors
*/
#define for_lisp_vector(v) \
if (!v); else \
if (int it_index = 0); else \
for (auto it = v->value.vector.data; \
it_index < v->value.vector.length; \
it=v->value.vector.data+(++it_index))
/*
* iterate over lisp lists
*/
#define for_lisp_list(l) \
if (!l); else \
if (int it_index = 0); else \
for (Lisp_Object* head = l, *it; \
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
head = head->value.pair.rest, ++it_index)
-35
View File
@@ -16,41 +16,6 @@
# define if_linux if constexpr (true)
#endif
/*
* iterate over lisp vectors
*/
#define for_lisp_vector(v) \
if (!v); else \
if (int it_index = 0); else \
for (auto it = v->value.vector.data; \
it_index < v->value.vector.length; \
it=v->value.vector.data+(++it_index))
/*
* iterate over lisp lists
*/
#define for_lisp_list(l) \
if (!l); else \
if (int it_index = 0); else \
for (Lisp_Object* head = l, *it; \
Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
head = head->value.pair.rest, ++it_index)
/*
#define assert(cond) \
if_debug { \
if (!cond) { \
if (log_level == Log_Level::Debug) { \
printf("Assertion failed: %s %d", __FILE__, __LINE__); \
} \
debug_break(); \
} \
} else {} \
*/
#define console_normal "\x1B[0m"
#define console_red "\x1B[31m"
#define console_green "\x1B[32m"
+3 -3
View File
@@ -259,9 +259,9 @@ proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_O
result = &function->value.function.args;
}
::new (&(result->positional.symbols)) Array_List<Lisp_Object*>;
::new (&(result->keyword.keywords)) Array_List<Lisp_Object*>;
::new (&(result->keyword.values)) Array_List<Lisp_Object*>;
::new (&result->positional.symbols) Array_List<Lisp_Object*>;
::new (&result->keyword.keywords) Array_List<Lisp_Object*>;
::new (&result->keyword.values) Array_List<Lisp_Object*>;
// first init the fields
// result->positional = create_positional_argument_list(16);
+3
View File
@@ -1,7 +1,10 @@
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
+6
View File
@@ -39,3 +39,9 @@ proc append_to_keyword_argument_list(Keyword_Arguments* args,
args->keywords.append(keyword);
args->values.append(default_value);
}
Lisp_Object::~Lisp_Object() {
if (Memory::get_type(this) == Lisp_Object_Type::HashMap) {
this->value.hashMap.~Hash_Map();
}
}
+3
View File
@@ -1,10 +1,13 @@
#include "libslime.cpp"
int main(int argc, char* argv[]) {
if (argc > 1) {
if (Slime::string_equal(argv[1], "--run-tests")) {
int res = Slime::run_all_tests();
// Slime::interprete_file((char*)"generate-docs.slime");
_CrtDumpMemoryLeaks();
return res ? 0 : 1;
}
+18 -6
View File
@@ -6,6 +6,8 @@ namespace Memory {
Hash_Map<char*, Lisp_Object*> global_symbol_table;
Hash_Map<char*, Lisp_Object*> global_keyword_table;
Hash_Map<char*, Environment*> file_to_env_map;
// ------------------
// lisp_objects
// ------------------
@@ -177,13 +179,23 @@ namespace Memory {
free_spots_in_string_memory.next_index = 0;
::new((&global_symbol_table)) Hash_Map<char*, Lisp_Object*>;
::new((&global_keyword_table)) Hash_Map<char*, Lisp_Object*>;
global_symbol_table.~Hash_Map();
global_keyword_table.~Hash_Map();
file_to_env_map.~Hash_Map();
::new(&global_symbol_table) Hash_Map<char*, Lisp_Object*>;
::new(&global_keyword_table) Hash_Map<char*, Lisp_Object*>;
::new(&file_to_env_map) Hash_Map<char*, Lisp_Object*>;
try_void Parser::standard_in = create_string("stdin");
object_memory.reset();
environment_memory.reset();
object_memory.~Bucket_Allocator();
// environment_memory.~Bucket_Allocator();
::new(&object_memory) Bucket_Allocator<Lisp_Object, 1024>;
::new(&environment_memory) Bucket_Allocator<Environment, 1024>;
next_free_spot_in_string_memory = string_memory;
@@ -373,7 +385,7 @@ namespace Memory {
return copy_lisp_object(n);
}
proc create_child_environment(Environment* parent) -> Environment* {
proc create_child_environment(Environment* parent) -> Environment* {
Environment* env = environment_memory.allocate();
@@ -404,7 +416,7 @@ namespace Memory {
try load_built_ins_into_environment();
built_in_load(Memory::create_string("pre.slime"));
try built_in_load(Memory::create_string("pre.slime"));
return ret;
}
+7 -8
View File
@@ -98,7 +98,6 @@ namespace Parser {
// get the atom
String* ret = Memory::create_string("", atom_length);
// char* atom = (char*)malloc(atom_length*sizeof(char)+1); // plus null char
strcpy(&ret->data, text+(*index_in_text));
// restore the original string
@@ -448,7 +447,7 @@ namespace Parser {
}
proc write_expanded_file(String* file_name, Array_List<Lisp_Object*> program) -> void {
proc write_expanded_file(String* file_name, Array_List<Lisp_Object*>* program) -> void {
const char* ext = ".expanded";
char* newName = (char*)calloc(10 + file_name->length, sizeof(char));
strcpy(newName, Memory::get_c_str(file_name));
@@ -465,21 +464,21 @@ namespace Parser {
exit(1);
}
for (int i = 0; i < program.next_index; ++i) {
for (int i = 0; i < program->next_index; ++i) {
// a macro will parse as nil for now, so we skip those
if (program.data[i] == Memory::nil)
if (program->data[i] == Memory::nil)
continue;
print(program.data[i], true, f);
print(program->data[i], true, f);
fprintf(f, "\n\n");
}
}
proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*> {
proc parse_program(String* file_name, char* text) -> Array_List<Lisp_Object*>* {
parser_file = file_name;
parser_line = 1;
parser_col = 0;
Array_List<Lisp_Object*> program;
Array_List<Lisp_Object*>* program = new Array_List<Lisp_Object*>;
int index_in_text = 0;
@@ -490,7 +489,7 @@ namespace Parser {
try_struct {
parsed = parse_expression(text, &index_in_text);
}
program.append(parsed);
program->append(parsed);
} break;
case ';':
case ' ':
+8 -1
View File
@@ -103,6 +103,11 @@ struct Arguments {
struct Environment {
Array_List<Environment*> parents;
Hash_Map<void*, Lisp_Object*> hm;
~Environment() {
parents.~Array_List();
hm.~Hash_Map();
}
};
struct Function {
@@ -123,7 +128,7 @@ struct Lisp_Object {
u64 flags;
Lisp_Object* userType; // keyword
String* docstring;
union {
union value {
Symbol symbol; // used for symbols and keywords
double number;
String* string;
@@ -134,7 +139,9 @@ struct Lisp_Object {
void* pointer;
Continuation continuation;
Hash_Map<Lisp_Object*, Lisp_Object*> hashMap;
~value() {}
} value;
~Lisp_Object();
};
struct Error {
+2 -1
View File
@@ -596,7 +596,7 @@ proc test_file(const char* file) -> testresult {
pop_environment();
};
built_in_load(Memory::create_string(file));
try built_in_load(Memory::create_string(file));
assert_no_error();
return pass;
@@ -654,6 +654,7 @@ proc run_all_tests() -> bool {
invoke_test_script("automata");
invoke_test_script("sicp");
invoke_test_script("hashmaps");
invoke_test_script("singular_imports");
// Memory::print_status();