Browse Source

[server] save `cf_expr_unoptimized` early

closes #8611
Simon Krajewski 6 năm trước cách đây
mục cha
commit
57dce1f3a4

+ 6 - 1
src/core/json/genjson.ml

@@ -519,7 +519,12 @@ and generate_class_field' ctx cfs cf =
 						None
 						None
 			in
 			in
 			begin match value with
 			begin match value with
-				| None -> jnull
+				| None ->
+					if Meta.has (Meta.Custom ":testHack") cf.cf_meta then begin match cf.cf_expr with
+						| Some e -> jobject ["testHack",jstring (s_expr_pretty false "" false (s_type (print_context())) e)] (* TODO: haha *)
+						| None -> jnull
+					end else
+						jnull
 				| Some e -> jobject ["string",jstring (Ast.Printer.s_expr e)]
 				| Some e -> jobject ["string",jstring (Ast.Printer.s_expr e)]
 			end
 			end
 		| GMMinimum ->
 		| GMMinimum ->

+ 19 - 5
src/filters/filters.ml

@@ -827,14 +827,28 @@ end
 let run com tctx main =
 let run com tctx main =
 	let detail_times = Common.raw_defined com "filter-times" in
 	let detail_times = Common.raw_defined com "filter-times" in
 	let new_types = List.filter (fun t ->
 	let new_types = List.filter (fun t ->
-		(match t with
+		let cached = is_cached t in
+		begin match t with
 			| TClassDecl cls ->
 			| TClassDecl cls ->
 				List.iter (fun (iface,_) -> add_descendant iface cls) cls.cl_implements;
 				List.iter (fun (iface,_) -> add_descendant iface cls) cls.cl_implements;
-				(match cls.cl_super with
+				begin match cls.cl_super with
 					| Some (csup,_) -> add_descendant csup cls
 					| Some (csup,_) -> add_descendant csup cls
-					| None -> ())
-			| _ -> ());
-		not (is_cached t)
+					| None -> ()
+				end;
+				(* Save cf_expr_unoptimized early: We want to inline with the original expression
+				   on the next compilation. *)
+				if not cached then begin
+					let field cf = match cf.cf_expr with
+						| Some {eexpr = TFunction tf} -> cf.cf_expr_unoptimized <- Some tf
+						| _ -> ()
+					in
+					List.iter field cls.cl_ordered_fields;
+					List.iter field cls.cl_ordered_statics;
+					Option.may field cls.cl_constructor;
+				end;
+			| _ -> ()
+		end;
+		not cached
 	) com.types in
 	) com.types in
 	NullSafety.run com new_types;
 	NullSafety.run com new_types;
 	(* PASS 1: general expression filters *)
 	(* PASS 1: general expression filters *)

+ 0 - 1
src/optimization/analyzer.ml

@@ -1030,7 +1030,6 @@ module Run = struct
 	let run_on_field ctx config c cf = match cf.cf_expr with
 	let run_on_field ctx config c cf = match cf.cf_expr with
 		| Some e when not (is_ignored cf.cf_meta) && not (Typecore.is_removable_field ctx cf) ->
 		| Some e when not (is_ignored cf.cf_meta) && not (Typecore.is_removable_field ctx cf) ->
 			let config = update_config_from_meta ctx.Typecore.com config cf.cf_meta in
 			let config = update_config_from_meta ctx.Typecore.com config cf.cf_meta in
-			(match e.eexpr with TFunction tf -> cf.cf_expr_unoptimized <- Some tf | _ -> ());
 			let actx = create_analyzer_context ctx.Typecore.com config e in
 			let actx = create_analyzer_context ctx.Typecore.com config e in
 			let debug() =
 			let debug() =
 				print_endline (Printf.sprintf "While analyzing %s.%s" (s_type_path c.cl_path) cf.cf_name);
 				print_endline (Printf.sprintf "While analyzing %s.%s" (s_type_path c.cl_path) cf.cf_name);

+ 2 - 2
tests/server/src/HaxeServerTestCase.hx

@@ -92,8 +92,8 @@ class HaxeServerTestCase implements ITest {
 		return false;
 		return false;
 	}
 	}
 
 
-	function getStoredType(typePackage:String, typeName:String) {
-		var storedTypes:Array<JsonModuleType<Any>> = try {
+	function getStoredType<T>(typePackage:String, typeName:String) {
+		var storedTypes:Array<JsonModuleType<T>> = try {
 			Json.parse(lastResult.stderr).result.result;
 			Json.parse(lastResult.stderr).result.result;
 		} catch (e:Dynamic) {
 		} catch (e:Dynamic) {
 			trace(e);
 			trace(e);

+ 14 - 0
tests/server/src/Main.hx

@@ -150,6 +150,20 @@ class ServerTests extends HaxeServerTestCase {
 			case _: false;
 			case _: false;
 		});
 		});
 	}
 	}
+
+	function testVectorInliner() {
+		vfs.putContent("Vector.hx", getTemplate("Vector.hx"));
+		vfs.putContent("VectorInliner.hx", getTemplate("VectorInliner.hx"));
+		var args = ["-main", "VectorInliner", "--interp"];
+		runHaxe(args);
+		vfs.touchFile("VectorInliner.hx");
+		runHaxeJson(args, cast "typer/compiledTypes" /* TODO */, {});
+		var type = getStoredType("", "VectorInliner");
+		function moreHack(s:String) {
+			return ~/[\r\n\t]/g.replace(s, "");
+		}
+		utest.Assert.equals("function() {_Vector.Vector_Impl_.toIntVector(null);}", moreHack(type.args.statics[0].expr.testHack)); // lmao
+	}
 }
 }
 
 
 class Main {
 class Main {

+ 14 - 0
tests/server/test/templates/Vector.hx

@@ -0,0 +1,14 @@
+@:multiType(T)
+abstract Vector<T>(Array<T>) {
+	function new();
+
+	public inline static function ofArray<T>(a:Array<T>):Vector<T> {
+		return new Vector<T>();
+	}
+
+	@:to static function toIntVector(t:Array<Int>)
+		return null;
+
+	@:to static function toObjectVector<T>(t:Array<T>)
+		return null;
+}

+ 5 - 0
tests/server/test/templates/VectorInliner.hx

@@ -0,0 +1,5 @@
+class VectorInliner {
+	@:testHack static function main() {
+		Vector.ofArray([1]);
+	}
+}