소스 검색

fixed cached modules classpath issue for macros
make sure that resources added through macros will be added again if we use the cached module

Nicolas Cannasse 13 년 전
부모
커밋
9f608ea5b4
5개의 변경된 파일72개의 추가작업 그리고 46개의 파일을 삭제
  1. 6 1
      interp.ml
  2. 17 5
      main.ml
  3. 2 0
      type.ml
  4. 1 0
      typeload.ml
  5. 46 40
      typer.ml

+ 6 - 1
interp.ml

@@ -101,6 +101,7 @@ type extern_api = {
 	get_build_fields : unit -> value;
 	define_type : value -> unit;
 	module_dependency : string -> string -> unit;
+	current_module : unit -> module_def;
 }
 
 type callstack = {
@@ -1916,7 +1917,11 @@ let macro_lib =
 		);
 		"add_resource", Fun2 (fun name data ->
 			match name, data with
-			| VString name, VString data -> Hashtbl.replace (ccom()).resources name data; VNull
+			| VString name, VString data -> 
+				Hashtbl.replace (ccom()).resources name data;
+				let m = (get_ctx()).curapi.current_module() in
+				m.m_extra.m_binded_res <- PMap.add name data m.m_extra.m_binded_res;
+				VNull
 			| _ -> error()
 		);
 		"local_type", Fun0 (fun() ->

+ 17 - 5
main.ml

@@ -398,6 +398,9 @@ and wait_loop boot_com host port =
 			| _ -> ()
 		) m.m_types
 	in
+	let check_module_path com m p =
+		m.m_extra.m_file = Common.get_full_path (Typeload.resolve_module_file com m.m_path (ref[]) p)
+	in
 	let modules_added = Hashtbl.create 0 in
 	Typeload.type_module_hook := (fun (ctx:Typecore.typer) mpath p ->
 		let com2 = ctx.Typecore.com in
@@ -407,7 +410,9 @@ and wait_loop boot_com host port =
 		let dep = ref None in
 		let rec check m =
 			try
-				Hashtbl.find added m.m_id
+				(match Hashtbl.find added m.m_id with
+				| None -> true
+				| x -> dep := x; false)
 			with Not_found -> try
 				!(Hashtbl.find modules_checked m.m_id)
 			with Not_found ->
@@ -415,12 +420,19 @@ and wait_loop boot_com host port =
 			Hashtbl.add modules_checked m.m_id ok;
 			try
 				let m = Hashtbl.find cache.c_modules (m.m_path,m.m_extra.m_sign) in
-				if m.m_extra.m_kind <> MFake && m.m_extra.m_file <> Common.get_full_path (Typeload.resolve_module_file com2 m.m_path (ref[]) p) then raise Not_found;
+				(match m.m_extra.m_kind with
+				| MFake -> () (* don't get classpath *)
+				| MCode -> if not (check_module_path com2 m p) then raise Not_found;
+				| MMacro when ctx.Typecore.in_macro -> if not (check_module_path com2 m p) then raise Not_found;
+				| MMacro ->
+					let _, mctx = Typer.get_macro_context ctx p in
+					if not (check_module_path mctx.Typecore.com m p) then raise Not_found;
+				);
 				if file_time m.m_extra.m_file <> m.m_extra.m_time then raise Not_found;
 				PMap.iter (fun _ m2 -> if not (check m2) then begin dep := Some m2; raise Not_found end) m.m_extra.m_deps;
 				true
 			with Not_found ->
-				Hashtbl.add added m.m_id false;
+				Hashtbl.add added m.m_id (match !dep with None -> Some m | x -> x);
 				ok := false;
 				!ok
 		in
@@ -428,9 +440,9 @@ and wait_loop boot_com host port =
 			if Hashtbl.mem added m.m_id then
 				()
 			else begin
-				Hashtbl.add added m.m_id true;
+				Hashtbl.add added m.m_id None;
 				(match m0.m_extra.m_kind, m.m_extra.m_kind with
-				| MCode, MMacro | MMacro, MCode -> 
+				| MCode, MMacro | MMacro, MCode ->
 					(* this was just a dependency to check : do not add to the context *)
 					()
 				| _ ->

+ 2 - 0
type.ml

@@ -238,6 +238,7 @@ and module_def_extra = {
 	mutable m_deps : (int,module_def) PMap.t;
 	mutable m_processed : int;
 	mutable m_kind : module_kind;
+	mutable m_binded_res : (string, string) PMap.t;
 }
 
 and module_kind =
@@ -307,6 +308,7 @@ let null_module = {
 			m_processed = 0;
 			m_deps = PMap.empty;
 			m_kind = MFake;
+			m_binded_res = PMap.empty;
 		};
 	}
 

+ 1 - 0
typeload.ml

@@ -1179,6 +1179,7 @@ let type_module ctx m file tdecls loadp =
 			m_deps = PMap.empty;
 			m_processed = 0;
 			m_kind = if ctx.in_macro then MMacro else MCode;
+			m_binded_res = PMap.empty;
 		};
 	} in
 	List.iter (fun (d,p) ->

+ 46 - 40
typer.ml

@@ -2392,6 +2392,7 @@ let make_macro_api ctx p =
 						m_deps = PMap.empty;
 						m_processed = 0;
 						m_kind = MFake;
+						m_binded_res = PMap.empty;
 					};
 				} in
 				Hashtbl.add fake_modules file mdep;
@@ -2400,8 +2401,52 @@ let make_macro_api ctx p =
 			add_dependency m mdep;
 			Hashtbl.replace ctx.g.modules mdep.m_path mdep
 		);
+		Interp.current_module = (fun() ->
+			ctx.current
+		);
 	}
 
+let get_macro_context ctx p =
+	let api = make_macro_api ctx p in
+	match ctx.g.macros with
+	| Some (select,ctx) ->
+		select();
+		api, ctx
+	| None ->
+		let com2 = Common.clone ctx.com in
+		ctx.com.get_macros <- (fun() -> Some com2);
+		com2.package_rules <- PMap.empty;
+		com2.main_class <- None;
+		com2.display <- false;
+		com2.dead_code_elimination <- false;
+		List.iter (fun p -> com2.defines <- PMap.remove (platform_name p) com2.defines) platforms;
+		com2.defines_signature <- None;
+		com2.class_path <- List.filter (fun s -> not (ExtString.String.exists s "/_std/")) com2.class_path;
+		com2.class_path <- List.map (fun p -> p ^ "neko" ^ "/_std/") com2.std_path @ com2.class_path;
+		com2.defines <- PMap.foldi (fun k _ acc ->
+			match k with
+			| "no_traces" -> acc
+			| _ when List.exists (fun (_,d) -> "flash" ^ d = k) Common.flash_versions -> acc
+			| _ -> PMap.add k () acc
+		) com2.defines PMap.empty;
+		Common.define com2 "macro";
+		Common.init_platform com2 Neko;
+		let ctx2 = ctx.g.do_create com2 in
+		let mctx = Interp.create com2 api in
+		let on_error = com2.error in
+		com2.error <- (fun e p -> Interp.set_error mctx true; on_error e p);
+		let macro = ((fun() -> Interp.select mctx), ctx2) in
+		ctx.g.macros <- Some macro;
+		ctx2.g.macros <- Some macro;
+		(* ctx2.g.core_api <- ctx.g.core_api; // causes some issues because of optional args and Null type in Flash9 *)
+		ignore(Typeload.load_module ctx2 (["haxe";"macro"],"Expr") p);
+		ignore(Typeload.load_module ctx2 (["haxe";"macro"],"Type") p);
+		finalize ctx2;
+		let _, types, _ = generate ctx2 in
+		Interp.add_types mctx types;
+		Interp.init mctx;
+		api, ctx2
+
 let load_macro ctx cpath f p =
 	(*
 		The time measured here takes into account both macro typing an init, but benchmarks
@@ -2409,46 +2454,7 @@ let load_macro ctx cpath f p =
 		typing the classes needed for macro execution.
 	*)
 	let t = macro_timer ctx "typing (+init)" in
-	let api = make_macro_api ctx p in
-	let ctx2 = (match ctx.g.macros with
-		| Some (select,ctx) ->
-			select();
-			ctx
-		| None ->
-			let com2 = Common.clone ctx.com in
-			ctx.com.get_macros <- (fun() -> Some com2);
-			com2.package_rules <- PMap.empty;
-			com2.main_class <- None;
-			com2.display <- false;
-			com2.dead_code_elimination <- false;
-			List.iter (fun p -> com2.defines <- PMap.remove (platform_name p) com2.defines) platforms;
-			com2.defines_signature <- None;
-			com2.class_path <- List.filter (fun s -> not (ExtString.String.exists s "/_std/")) com2.class_path;
-			com2.class_path <- List.map (fun p -> p ^ "neko" ^ "/_std/") com2.std_path @ com2.class_path;
-			com2.defines <- PMap.foldi (fun k _ acc ->
-				match k with
-				| "no_traces" -> acc
-				| _ when List.exists (fun (_,d) -> "flash" ^ d = k) Common.flash_versions -> acc
-				| _ -> PMap.add k () acc
-			) com2.defines PMap.empty;
-			Common.define com2 "macro";
-			Common.init_platform com2 Neko;
-			let ctx2 = ctx.g.do_create com2 in
-			let mctx = Interp.create com2 api in
-			let on_error = com2.error in
-			com2.error <- (fun e p -> Interp.set_error mctx true; on_error e p);
-			let macro = ((fun() -> Interp.select mctx), ctx2) in
-			ctx.g.macros <- Some macro;
-			ctx2.g.macros <- Some macro;
-			(* ctx2.g.core_api <- ctx.g.core_api; // causes some issues because of optional args and Null type in Flash9 *)
-			ignore(Typeload.load_module ctx2 (["haxe";"macro"],"Expr") p);
-			ignore(Typeload.load_module ctx2 (["haxe";"macro"],"Type") p);
-			finalize ctx2;
-			let _, types, _ = generate ctx2 in
-			Interp.add_types mctx types;
-			Interp.init mctx;
-			ctx2
-	) in
+	let api, ctx2 = get_macro_context ctx p in
 	let mctx = Interp.get_ctx() in
 	let m = (try Hashtbl.find ctx.g.types_module cpath with Not_found -> cpath) in
 	let mloaded = Typeload.load_module ctx2 m p in