瀏覽代碼

optimize Math.floor/ceil(float constant) (closes #4223)

Simon Krajewski 10 年之前
父節點
當前提交
a3b53ddaea
共有 2 個文件被更改,包括 82 次插入0 次删除
  1. 18 0
      optimizer.ml
  2. 64 0
      tests/optimization/src/issues/Issue4223.hx

+ 18 - 0
optimizer.ml

@@ -162,6 +162,24 @@ let api_inline ctx c field params p =
 			None (* out range, keep platform-specific behavior *)
 		| _ ->
 			Some { eexpr = TConst (TInt (Int32.of_float f)); etype = ctx.t.tint; epos = p })
+	| ([],"Math"),"ceil",[{ eexpr = TConst (TFloat f) }] ->
+		let f = float_of_string f in
+		(match classify_float f with
+		| FP_infinite | FP_nan ->
+			None
+		| _ when f <= Int32.to_float Int32.min_int -. 1. || f >= Int32.to_float Int32.max_int ->
+			None (* out range, keep platform-specific behavior *)
+		| _ ->
+			Some { eexpr = TConst (TInt (Int32.of_float (ceil f))); etype = ctx.t.tint; epos = p })
+	| ([],"Math"),"floor",[{ eexpr = TConst (TFloat f) }] ->
+		let f = float_of_string f in
+		(match classify_float f with
+		| FP_infinite | FP_nan ->
+			None
+		| _ when f <= Int32.to_float Int32.min_int || f >= Int32.to_float Int32.max_int +. 1. ->
+			None (* out range, keep platform-specific behavior *)
+		| _ ->
+			Some { eexpr = TConst (TInt (Int32.of_float (floor f))); etype = ctx.t.tint; epos = p })
 	| (["cs"],"Lib"),("fixed" | "checked" | "unsafe"),[e] ->
 			Some (mk_untyped_call ("__" ^ field ^ "__") p [e])
 	| (["cs"],"Lib"),("lock"),[obj;block] ->

+ 64 - 0
tests/optimization/src/issues/Issue4223.hx

@@ -0,0 +1,64 @@
+package issues;
+
+@:analyzer(no_local_dce)
+class Issue4223 {
+	@:js('4;')
+	static function testCeilPos() {
+		Math.ceil(3.6);
+	}
+
+	@:js('-3;')
+	static function testCeilNeg() {
+		Math.ceil(-3.6);
+	}
+
+	@:js('2147483647;')
+	static function testCeilMax() {
+		Math.ceil(2147483646.5);
+	}
+
+	@:js('-2147483648;')
+	static function testCeilMin() {
+		Math.ceil(-2147483648.5);
+	}
+
+	@:js('Math.ceil(2147483647.5);')
+	static function testCeilOver() {
+		Math.ceil(2147483647.5);
+	}
+
+	@:js('Math.ceil(-2147483649.5);')
+	static function testCeilUnder() {
+		Math.ceil(-2147483649.5);
+	}
+
+	@:js('3;')
+	static function testFloorPos() {
+		Math.floor(3.6);
+	}
+
+	@:js('-4;')
+	static function testFloorNeg() {
+		Math.floor(-3.6);
+	}
+
+	@:js('2147483647;')
+	static function testFloorMax() {
+		Math.floor(2147483647.5);
+	}
+
+	@:js('-2147483648;')
+	static function testFloorMin() {
+		Math.floor(-2147483647.5);
+	}
+
+	@:js('Math.floor(2147483648.5);')
+	static function testFloorOver() {
+		Math.floor(2147483648.5);
+	}
+
+	@:js('Math.ceil(-2147483649.5);')
+	static function testFloorUnder() {
+		Math.ceil(-2147483649.5);
+	}
+}