Browse Source

respect `@:pure` when checking for side-effects

Simon Krajewski 9 years ago
parent
commit
45351d474b

+ 1 - 0
src/optimization/analyzer.ml

@@ -814,6 +814,7 @@ module LocalDce = struct
 			| TCall ({ eexpr = TField(_,FStatic({ cl_path = ([],"Std") },{ cf_name = "string" })) },args) -> Type.iter loop e
 			| TCall ({eexpr = TField(_,FEnum _)},_) -> Type.iter loop e
 			| TCall ({eexpr = TConst (TString ("phi" | "fun"))},_) -> ()
+			| TCall({eexpr = TField(e1,fa)},el) -> Optimizer.field_call_has_side_effect loop e1 fa el
 			| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 			| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
 			| TFor _ -> raise Exit

+ 9 - 0
src/optimization/optimizer.ml

@@ -25,12 +25,21 @@ open Typecore
 (* ---------------------------------------------------------------------- *)
 (* API OPTIMIZATIONS *)
 
+let field_call_has_side_effect f e1 fa el =
+	begin match extract_field fa with
+		| Some cf when Meta.has Meta.Pure cf.cf_meta -> ()
+		| _ -> raise Exit
+	end;
+	f e1;
+	List.iter f el
+
 (* tells if an expression causes side effects. This does not account for potential null accesses (fields/arrays/ops) *)
 let has_side_effect e =
 	let rec loop e =
 		match e.eexpr with
 		| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> ()
 		| TCall ({ eexpr = TField(_,FStatic({ cl_path = ([],"Std") },{ cf_name = "string" })) },args) -> Type.iter loop e
+		| TCall({eexpr = TField(e1,fa)},el) -> field_call_has_side_effect loop e1 fa el
 		| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
 		| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _

+ 1 - 0
tests/optimization/src/TestJs.hx

@@ -567,6 +567,7 @@ class TestJs {
 		return call(d2, d1);
 	}
 
+	@:impure
 	static function getInt(?d:Dynamic) { return 1; }
 	static function getArray() { return [0, 1]; }
 	@:impure

+ 1 - 0
tests/optimization/src/TestLocalDce.hx

@@ -194,5 +194,6 @@ class TestLocalDce {
 		trace(s);
 	}
 
+	@:impure
 	static function keep(v:Dynamic) { return v; }
 }