Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
9f608ea5b4
5 mainītis faili ar 72 papildinājumiem un 46 dzēšanām
  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