Przeglądaj źródła

[tre] don't apply to modifyable fields
fixes #8989

Aleksandr Kuzmenko 5 lat temu
rodzic
commit
4c8fc82830
2 zmienionych plików z 22 dodań i 1 usunięć
  1. 7 1
      src/filters/tre.ml
  2. 15 0
      tests/optimization/src/TestTreBehavior.hx

+ 7 - 1
src/filters/tre.ml

@@ -203,7 +203,13 @@ let rec has_tail_recursion is_recursive_call cancel_tre function_end e =
 let run ctx e =
 let run ctx e =
 	match e.eexpr with
 	match e.eexpr with
 	| TFunction fn ->
 	| TFunction fn ->
-		let is_tre_eligible = ctx.curfun = FunStatic || has_class_field_flag ctx.curfield CfFinal in
+		let is_tre_eligible =
+			match ctx.curfield.cf_kind with
+			| Method MethDynamic -> false
+			| Method MethInline -> true
+			| Method _ when ctx.curfun = FunStatic -> true
+			| _ -> has_class_field_flag ctx.curfield CfFinal
+			in
 		let is_recursive_call callee args =
 		let is_recursive_call callee args =
 			is_tre_eligible && is_recursive_method_call ctx.curclass ctx.curfield callee args
 			is_tre_eligible && is_recursive_method_call ctx.curclass ctx.curfield callee args
 		in
 		in

+ 15 - 0
tests/optimization/src/TestTreBehavior.hx

@@ -35,6 +35,21 @@ class TestTreBehavior extends TestBase {
 		assertEquals(2, parent.rec(2));
 		assertEquals(2, parent.rec(2));
 		assertEquals(5, child.rec(2));
 		assertEquals(5, child.rec(2));
 	}
 	}
+
+	function testSelfModifyingFields() {
+		assertEquals(1, selfModifyingMethod());
+		assertEquals(2, selfModifyingVar());
+	}
+
+	static dynamic function selfModifyingMethod():Int {
+		selfModifyingMethod = () -> 1;
+		return selfModifyingMethod();
+	}
+
+	static var selfModifyingVar:()->Int = function() {
+		selfModifyingVar = () -> 2;
+		return selfModifyingVar();
+	}
 }
 }
 
 
 private class Parent {
 private class Parent {