Browse Source

Merge pull request #19828 from jjay/fix_yield_leak

Fix memory leak in GDScript during infinnity loops with yields
Max Hilbrunner 7 years ago
parent
commit
aad475937b
2 changed files with 11 additions and 11 deletions
  1. 10 10
      modules/gdscript/gdscript_function.cpp
  2. 1 1
      modules/gdscript/gdscript_function.h

+ 10 - 10
modules/gdscript/gdscript_function.cpp

@@ -1552,7 +1552,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
 		GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret);
 		if (gdfs && gdfs->function == function) {
 			completed = false;
-			gdfs->previous_state = Ref<GDScriptFunctionState>(this);
+			gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this);
 		}
 	}
 
@@ -1560,10 +1560,10 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
 	state.result = Variant();
 
 	if (completed) {
-		GDScriptFunctionState *state = this;
-		while (state != NULL) {
-			state->emit_signal("completed", ret);
-			state = *(state->previous_state);
+		if (first_state.is_valid()) {
+			first_state->emit_signal("completed", ret);
+		} else {
+			emit_signal("completed", ret);
 		}
 	}
 
@@ -1614,7 +1614,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
 		GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret);
 		if (gdfs && gdfs->function == function) {
 			completed = false;
-			gdfs->previous_state = Ref<GDScriptFunctionState>(this);
+			gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this);
 		}
 	}
 
@@ -1622,10 +1622,10 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
 	state.result = Variant();
 
 	if (completed) {
-		GDScriptFunctionState *state = this;
-		while (state != NULL) {
-			state->emit_signal("completed", ret);
-			state = *(state->previous_state);
+		if (first_state.is_valid()) {
+			first_state->emit_signal("completed", ret);
+		} else {
+			emit_signal("completed", ret);
 		}
 	}
 

+ 1 - 1
modules/gdscript/gdscript_function.h

@@ -234,7 +234,7 @@ class GDScriptFunctionState : public Reference {
 	GDScriptFunction *function;
 	GDScriptFunction::CallState state;
 	Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
-	Ref<GDScriptFunctionState> previous_state;
+	Ref<GDScriptFunctionState> first_state;
 
 protected:
 	static void _bind_methods();