Browse Source

Several memory leaks fixed.

Marco Bambini 8 years ago
parent
commit
95da25dab6

+ 1 - 0
src/compiler/gravity_ircode.c

@@ -63,6 +63,7 @@ void ircode_free (ircode_t *code) {
 	}
 	}
 	
 	
 	marray_destroy(*code->list);
 	marray_destroy(*code->list);
+    marray_destroy(code->context);
 	marray_destroy(code->registers);
 	marray_destroy(code->registers);
 	marray_destroy(code->label_true);
 	marray_destroy(code->label_true);
 	marray_destroy(code->label_false);
 	marray_destroy(code->label_false);

+ 12 - 5
src/compiler/gravity_parser.c

@@ -2024,6 +2024,9 @@ loop:
 		REPORT_ERROR(token, "Unable to load file %s.", module_name);
 		REPORT_ERROR(token, "Unable to load file %s.", module_name);
 	}
 	}
 	
 	
+    // cleanup memory
+    if (module_name) mem_free(module_name);
+    
 	// check for optional comma
 	// check for optional comma
 	if (gravity_lexer_peek(lexer) == TOK_OP_COMMA) {
 	if (gravity_lexer_peek(lexer) == TOK_OP_COMMA) {
 		gravity_lexer_next(lexer); // consume TOK_OP_COMMA
 		gravity_lexer_next(lexer); // consume TOK_OP_COMMA
@@ -2484,16 +2487,17 @@ static gnode_t *parse_statement (gravity_parser_t *parser) {
 // MARK: - Internal functions -
 // MARK: - Internal functions -
 
 
 static void parser_register_core_classes (gravity_parser_t *parser) {
 static void parser_register_core_classes (gravity_parser_t *parser) {
-	const char **list = NULL;
-	uint32_t n = gravity_core_identifiers(&list);
-	if (!n) return;
+	const char **list = gravity_core_identifiers();
 	
 	
 	// for each core identifier create a dummy extern variable node
 	// for each core identifier create a dummy extern variable node
 	gnode_r	*decls = gnode_array_create();
 	gnode_r	*decls = gnode_array_create();
-	for (uint32_t i=0; i<n; ++i) {
+    
+    uint32_t i = 0;
+    while (list[i]) {
 		const char *identifier = list[i];
 		const char *identifier = list[i];
 		gnode_t *node = gnode_variable_create(NO_TOKEN, string_dup(identifier), NULL, 0, NULL, LAST_DECLARATION());
 		gnode_t *node = gnode_variable_create(NO_TOKEN, string_dup(identifier), NULL, 0, NULL, LAST_DECLARATION());
 		gnode_array_push(decls, node);
 		gnode_array_push(decls, node);
+        ++i;
 	}
 	}
 	
 	
 	// register a variable declaration node in global statements
 	// register a variable declaration node in global statements
@@ -2618,7 +2622,10 @@ void gravity_parser_free (gravity_parser_t *parser) {
     // parser->declarations is used to keep track of nodes hierarchy and it contains pointers to
     // parser->declarations is used to keep track of nodes hierarchy and it contains pointers to
     // parser->statements nodes so there is no need to free it using node_array_free because nodes
     // parser->statements nodes so there is no need to free it using node_array_free because nodes
     // are freed when AST (parser->statements) is freed
     // are freed when AST (parser->statements) is freed
-	if (parser->declarations) marray_destroy(*parser->declarations);
+    if (parser->declarations) {
+        marray_destroy(*parser->declarations);
+        mem_free(parser->declarations);
+    }
     
     
 	// parser->statements is returned from gravity_parser_run
 	// parser->statements is returned from gravity_parser_run
 	// and must be deallocated using gnode_free
 	// and must be deallocated using gnode_free

+ 58 - 10
src/runtime/gravity_core.c

@@ -2212,13 +2212,31 @@ static bool system_exit (gravity_vm *vm, gravity_value_t *args, uint16_t nargs,
 
 
 // MARK: - CORE -
 // MARK: - CORE -
 
 
-static gravity_closure_t *computed_property (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func) {
+static gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func) {
 	gravity_closure_t *getter_closure = (getter_func) ? gravity_closure_new(vm, getter_func) : NULL;
 	gravity_closure_t *getter_closure = (getter_func) ? gravity_closure_new(vm, getter_func) : NULL;
 	gravity_closure_t *setter_closure = (setter_func) ? gravity_closure_new(vm, setter_func) : NULL;
 	gravity_closure_t *setter_closure = (setter_func) ? gravity_closure_new(vm, setter_func) : NULL;
 	gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, getter_closure, setter_closure);
 	gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, getter_closure, setter_closure);
 	return gravity_closure_new(vm, f);
 	return gravity_closure_new(vm, f);
 }
 }
 
 
+static void computed_property_free (gravity_closure_t *closure) {
+    gravity_closure_t *getter = (gravity_closure_t *)closure->f->special[0];
+    gravity_closure_t *setter = (closure->f->special[0] != closure->f->special[1]) ? (gravity_closure_t *)closure->f->special[1] : NULL;
+    if (getter) {
+        gravity_function_t *f = getter->f;
+        gravity_closure_free(NULL, getter);
+        gravity_function_free(NULL, f);
+    }
+    if (setter) {
+        gravity_function_t *f = setter->f;
+        gravity_closure_free(NULL, setter);
+        gravity_function_free(NULL, f);
+    }
+    
+    gravity_closure_free(NULL, closure);
+    if (closure->f) gravity_function_free(NULL, closure->f);
+}
+
 static void gravity_core_init (void) {
 static void gravity_core_init (void) {
 	// this function must be executed ONCE
 	// this function must be executed ONCE
 	if (core_inited) return;
 	if (core_inited) return;
@@ -2327,7 +2345,8 @@ static void gravity_core_init (void) {
 	gravity_class_bind(gravity_class_closure, "apply", NEW_CLOSURE_VALUE(closure_apply));
 	gravity_class_bind(gravity_class_closure, "apply", NEW_CLOSURE_VALUE(closure_apply));
 	
 	
 	// LIST CLASS
 	// LIST CLASS
-	gravity_class_bind(gravity_class_list, "count", VALUE_FROM_OBJECT(computed_property(NULL, NEW_FUNCTION(list_count), NULL)));
+    gravity_closure_t *closure = computed_property_create(NULL, NEW_FUNCTION(list_count), NULL);
+	gravity_class_bind(gravity_class_list, "count", VALUE_FROM_OBJECT(closure));
 	gravity_class_bind(gravity_class_list, ITERATOR_INIT_FUNCTION, NEW_CLOSURE_VALUE(list_iterator));
 	gravity_class_bind(gravity_class_list, ITERATOR_INIT_FUNCTION, NEW_CLOSURE_VALUE(list_iterator));
 	gravity_class_bind(gravity_class_list, ITERATOR_NEXT_FUNCTION, NEW_CLOSURE_VALUE(list_iterator_next));
 	gravity_class_bind(gravity_class_list, ITERATOR_NEXT_FUNCTION, NEW_CLOSURE_VALUE(list_iterator_next));
 	gravity_class_bind(gravity_class_list, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(list_loadat));
 	gravity_class_bind(gravity_class_list, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(list_loadat));
@@ -2344,7 +2363,8 @@ static void gravity_core_init (void) {
 	// MAP CLASS
 	// MAP CLASS
 	gravity_class_bind(gravity_class_map, "keys", NEW_CLOSURE_VALUE(map_keys));
 	gravity_class_bind(gravity_class_map, "keys", NEW_CLOSURE_VALUE(map_keys));
 	gravity_class_bind(gravity_class_map, "remove", NEW_CLOSURE_VALUE(map_remove));
 	gravity_class_bind(gravity_class_map, "remove", NEW_CLOSURE_VALUE(map_remove));
-	gravity_class_bind(gravity_class_map, "count", VALUE_FROM_OBJECT(computed_property(NULL, NEW_FUNCTION(map_count), NULL)));
+    closure = computed_property_create(NULL, NEW_FUNCTION(map_count), NULL);
+	gravity_class_bind(gravity_class_map, "count", VALUE_FROM_OBJECT(closure));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_LOOP_NAME, NEW_CLOSURE_VALUE(map_loop));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_LOOP_NAME, NEW_CLOSURE_VALUE(map_loop));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(map_loadat));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(map_loadat));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_STOREAT_NAME, NEW_CLOSURE_VALUE(map_storeat));
 	gravity_class_bind(gravity_class_map, GRAVITY_INTERNAL_STOREAT_NAME, NEW_CLOSURE_VALUE(map_storeat));
@@ -2355,7 +2375,8 @@ static void gravity_core_init (void) {
 	#endif
 	#endif
 	
 	
 	// RANGE CLASS
 	// RANGE CLASS
-	gravity_class_bind(gravity_class_range, "count", VALUE_FROM_OBJECT(computed_property(NULL, NEW_FUNCTION(range_count), NULL)));
+    closure = computed_property_create(NULL, NEW_FUNCTION(range_count), NULL);
+	gravity_class_bind(gravity_class_range, "count", VALUE_FROM_OBJECT(closure));
 	gravity_class_bind(gravity_class_range, ITERATOR_INIT_FUNCTION, NEW_CLOSURE_VALUE(range_iterator));
 	gravity_class_bind(gravity_class_range, ITERATOR_INIT_FUNCTION, NEW_CLOSURE_VALUE(range_iterator));
 	gravity_class_bind(gravity_class_range, ITERATOR_NEXT_FUNCTION, NEW_CLOSURE_VALUE(range_iterator_next));
 	gravity_class_bind(gravity_class_range, ITERATOR_NEXT_FUNCTION, NEW_CLOSURE_VALUE(range_iterator_next));
 	gravity_class_bind(gravity_class_range, "contains", NEW_CLOSURE_VALUE(range_contains));
 	gravity_class_bind(gravity_class_range, "contains", NEW_CLOSURE_VALUE(range_contains));
@@ -2431,7 +2452,8 @@ static void gravity_core_init (void) {
 	gravity_class_bind(gravity_class_string, GRAVITY_OPERATOR_NEG_NAME, NEW_CLOSURE_VALUE(operator_string_neg));
 	gravity_class_bind(gravity_class_string, GRAVITY_OPERATOR_NEG_NAME, NEW_CLOSURE_VALUE(operator_string_neg));
 	gravity_class_bind(gravity_class_string, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(string_loadat));
 	gravity_class_bind(gravity_class_string, GRAVITY_INTERNAL_LOADAT_NAME, NEW_CLOSURE_VALUE(string_loadat));
 	gravity_class_bind(gravity_class_string, GRAVITY_INTERNAL_STOREAT_NAME, NEW_CLOSURE_VALUE(string_storeat));
 	gravity_class_bind(gravity_class_string, GRAVITY_INTERNAL_STOREAT_NAME, NEW_CLOSURE_VALUE(string_storeat));
-	gravity_class_bind(gravity_class_string, "length", VALUE_FROM_OBJECT(computed_property(NULL, NEW_FUNCTION(string_length), NULL)));
+    closure = computed_property_create(NULL, NEW_FUNCTION(string_length), NULL);
+	gravity_class_bind(gravity_class_string, "length", VALUE_FROM_OBJECT(closure));
 	gravity_class_bind(gravity_class_string, "index", NEW_CLOSURE_VALUE(string_index));
 	gravity_class_bind(gravity_class_string, "index", NEW_CLOSURE_VALUE(string_index));
 	gravity_class_bind(gravity_class_string, "count", NEW_CLOSURE_VALUE(string_count));
 	gravity_class_bind(gravity_class_string, "count", NEW_CLOSURE_VALUE(string_count));
 	gravity_class_bind(gravity_class_string, "repeat", NEW_CLOSURE_VALUE(string_repeat));
 	gravity_class_bind(gravity_class_string, "repeat", NEW_CLOSURE_VALUE(string_repeat));
@@ -2478,7 +2500,8 @@ static void gravity_core_init (void) {
 	gravity_class_bind(system_meta, GRAVITY_SYSTEM_PUT_NAME, NEW_CLOSURE_VALUE(system_put));
 	gravity_class_bind(system_meta, GRAVITY_SYSTEM_PUT_NAME, NEW_CLOSURE_VALUE(system_put));
 	gravity_class_bind(system_meta, "exit", NEW_CLOSURE_VALUE(system_exit));
 	gravity_class_bind(system_meta, "exit", NEW_CLOSURE_VALUE(system_exit));
 	
 	
-	gravity_value_t value = VALUE_FROM_OBJECT(computed_property(NULL, NEW_FUNCTION(system_get), NEW_FUNCTION(system_set)));
+    closure = computed_property_create(NULL, NEW_FUNCTION(system_get), NEW_FUNCTION(system_set));
+	gravity_value_t value = VALUE_FROM_OBJECT(closure);
 	gravity_class_bind(system_meta, "gcenabled", value);
 	gravity_class_bind(system_meta, "gcenabled", value);
 	gravity_class_bind(system_meta, "gcminthreshold", value);
 	gravity_class_bind(system_meta, "gcminthreshold", value);
 	gravity_class_bind(system_meta, "gcthreshold", value);
 	gravity_class_bind(system_meta, "gcthreshold", value);
@@ -2516,6 +2539,32 @@ void gravity_core_free (void) {
 	// it is just called when we need to internally check for memory leaks
 	// it is just called when we need to internally check for memory leaks
 	
 	
 	mem_check(false);
 	mem_check(false);
+    // computed properties are not registered inside VM gc so they need to be manually freed here
+    {
+        STATICVALUE_FROM_STRING(key, "count", strlen("count"));
+        gravity_closure_t *list_count = gravity_class_lookup_closure(gravity_class_list, key);
+        computed_property_free(list_count);
+        gravity_hash_remove(gravity_class_list->htable, key);
+        gravity_closure_t *map_count = gravity_class_lookup_closure(gravity_class_map, key);
+        computed_property_free(map_count);
+        gravity_hash_remove(gravity_class_map->htable, key);
+        gravity_closure_t *range_count = gravity_class_lookup_closure(gravity_class_range, key);
+        computed_property_free(range_count);
+        gravity_hash_remove(gravity_class_range->htable, key);
+    }
+    {
+        STATICVALUE_FROM_STRING(key, "length", strlen("length"));
+        gravity_closure_t *string_length = gravity_class_lookup_closure(gravity_class_string, key);
+        computed_property_free(string_length);
+        gravity_hash_remove(gravity_class_string->htable, key);
+    }
+    {
+        STATICVALUE_FROM_STRING(key, "gcenabled", strlen("gcenabled"));
+        gravity_closure_t *system_gcenabled = gravity_class_lookup_closure(gravity_class_get_meta(gravity_class_system), key);
+        computed_property_free(system_gcenabled);
+        gravity_hash_remove(gravity_class_get_meta(gravity_class_system)->htable, key);
+    }
+        
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_int));
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_int));
 	gravity_class_free_core(NULL, gravity_class_int);
 	gravity_class_free_core(NULL, gravity_class_int);
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_float));
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_float));
@@ -2577,13 +2626,12 @@ void gravity_core_free (void) {
 	core_inited = false;
 	core_inited = false;
 }
 }
 
 
-uint32_t gravity_core_identifiers (const char ***id) {
+const char **gravity_core_identifiers (void) {
 	static const char *list[] = {GRAVITY_CLASS_OBJECT_NAME, GRAVITY_CLASS_CLASS_NAME, GRAVITY_CLASS_BOOL_NAME, GRAVITY_CLASS_NULL_NAME,
 	static const char *list[] = {GRAVITY_CLASS_OBJECT_NAME, GRAVITY_CLASS_CLASS_NAME, GRAVITY_CLASS_BOOL_NAME, GRAVITY_CLASS_NULL_NAME,
 		GRAVITY_CLASS_INT_NAME, GRAVITY_CLASS_FLOAT_NAME, GRAVITY_CLASS_FUNCTION_NAME, GRAVITY_CLASS_FIBER_NAME, GRAVITY_CLASS_STRING_NAME,
 		GRAVITY_CLASS_INT_NAME, GRAVITY_CLASS_FLOAT_NAME, GRAVITY_CLASS_FUNCTION_NAME, GRAVITY_CLASS_FIBER_NAME, GRAVITY_CLASS_STRING_NAME,
 		GRAVITY_CLASS_INSTANCE_NAME, GRAVITY_CLASS_LIST_NAME, GRAVITY_CLASS_MAP_NAME, GRAVITY_CLASS_RANGE_NAME, GRAVITY_CLASS_SYSTEM_NAME,
 		GRAVITY_CLASS_INSTANCE_NAME, GRAVITY_CLASS_LIST_NAME, GRAVITY_CLASS_MAP_NAME, GRAVITY_CLASS_RANGE_NAME, GRAVITY_CLASS_SYSTEM_NAME,
-		GRAVITY_CLASS_CLOSURE_NAME, GRAVITY_CLASS_UPVALUE_NAME};
-	if (id) *id = list;
-	return (sizeof(list) / sizeof(const char *));
+		GRAVITY_CLASS_CLOSURE_NAME, GRAVITY_CLASS_UPVALUE_NAME, NULL};
+    return list;
 }
 }
 
 
 void gravity_core_register (gravity_vm *vm) {
 void gravity_core_register (gravity_vm *vm) {

+ 1 - 1
src/runtime/gravity_core.h

@@ -19,7 +19,7 @@ extern "C" {
 GRAVITY_API void gravity_core_register (gravity_vm *vm);
 GRAVITY_API void gravity_core_register (gravity_vm *vm);
 GRAVITY_API bool gravity_iscore_class (gravity_class_t *c);
 GRAVITY_API bool gravity_iscore_class (gravity_class_t *c);
 GRAVITY_API void gravity_core_free (void);
 GRAVITY_API void gravity_core_free (void);
-GRAVITY_API uint32_t gravity_core_identifiers (const char ***id);
+GRAVITY_API const char **gravity_core_identifiers (void);
 GRAVITY_API gravity_class_t *gravity_core_class_from_name (const char *name);
 GRAVITY_API gravity_class_t *gravity_core_class_from_name (const char *name);
 
 
 // conversion functions
 // conversion functions

+ 1 - 1
src/shared/gravity_value.c

@@ -362,7 +362,7 @@ static void gravity_class_free_internal (gravity_vm *vm, gravity_class_t *c, boo
 	
 	
 	DEBUG_FREE("FREE %s", gravity_object_debug((gravity_object_t *)c));
 	DEBUG_FREE("FREE %s", gravity_object_debug((gravity_object_t *)c));
 	
 	
-	// check if bridged data needs to be freeed too
+	// check if bridged data needs to be freed too
 	if (c->xdata && vm) {
 	if (c->xdata && vm) {
 		gravity_delegate_t *delegate = gravity_vm_delegate(vm);
 		gravity_delegate_t *delegate = gravity_vm_delegate(vm);
 		if (delegate && delegate->bridge_free) delegate->bridge_free(vm, (gravity_object_t *)c);
 		if (delegate && delegate->bridge_free) delegate->bridge_free(vm, (gravity_object_t *)c);