Browse Source

fixed inline unbound var detection by annotating these in metadata (we don't always have our ctx.locals up to date)

Nicolas Cannasse 11 years ago
parent
commit
8162a0ebaf
5 changed files with 15 additions and 9 deletions
  1. 1 0
      ast.ml
  2. 4 1
      codegen.ml
  3. 1 0
      common.ml
  4. 6 7
      optimizer.ml
  5. 3 1
      typer.ml

+ 1 - 0
ast.ml

@@ -130,6 +130,7 @@ module Meta = struct
 		| Transient
 		| ValueUsed
 		| Volatile
+		| Unbound
 		| UnifyMinDynamic
 		| Unreflective
 		| Unsafe

+ 4 - 1
codegen.ml

@@ -260,6 +260,7 @@ let generic_substitute_expr gctx e =
 			Hashtbl.find vars v.v_id
 		with Not_found ->
 			let v2 = alloc_var v.v_name (generic_substitute_type gctx v.v_type) in
+			v2.v_meta <- v.v_meta;
 			Hashtbl.add vars v.v_id v2;
 			v2
 	in
@@ -1092,7 +1093,9 @@ let captured_vars com e =
 		mk (TVars [av,Some (mk (TArrayDecl [mk (TLocal v) v.v_type pos]) av.v_type pos)]) t.tvoid pos
 
 	and mk_var v used =
-		alloc_var v.v_name (PMap.find v.v_id used)
+		let v2 = alloc_var v.v_name (PMap.find v.v_id used) in
+		v2.v_meta <- v.v_meta;
+		v2
 
 	and wrap used e =
 		match e.eexpr with

+ 1 - 0
common.ml

@@ -419,6 +419,7 @@ module MetaInfo = struct
 		| Transient -> ":transient",("Adds the 'transient' flag to the class field",[Platform Java; UsedOn TClassField])
 		| ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[Internal])
 		| Volatile -> ":volatile",("",[Platforms [Java;Cs]])
+		| Unbound -> ":unbound", ("Compiler internal to denote unbounded global variable",[])
 		| UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField])
 		| Unreflective -> ":unreflective",("",[Platform Cpp])
 		| Unsafe -> ":unsafe",("Declares a class, or a method with the C#'s 'unsafe' flag",[Platform Cs; UsedOnEither [TClass;TClassField]])

+ 6 - 7
optimizer.ml

@@ -135,6 +135,7 @@ let rec type_inline ctx cf f ethis params tret config p force =
 				i_force_temp = false;
 				i_read = 0;
 			} in
+			i.i_subst.v_meta <- v.v_meta;
 			Hashtbl.add locals v.v_id i;
 			Hashtbl.add locals i.i_subst.v_id i;
 			i
@@ -142,10 +143,11 @@ let rec type_inline ctx cf f ethis params tret config p force =
 	let read_local v =
 		try
 			Hashtbl.find locals v.v_id
-		with Not_found -> try
-			(* if it's in our current local context, it's because we're inlining a local function *)
-			let v2 = if v.v_name.[0] = '`' then v else PMap.find v.v_name ctx.locals in
-			if v != v2 then raise Not_found;
+		with Not_found ->
+			(* make sure to duplicate unbound inline variable to prevent dependency leak when unifying monomorph *)
+			if has_meta Meta.Unbound v.v_meta then local v else
+			let v = v in
+			prerr_endline v.v_name;
 			{
 				i_var = v;
 				i_subst = v;
@@ -154,9 +156,6 @@ let rec type_inline ctx cf f ethis params tret config p force =
 				i_force_temp = false;
 				i_read = 0;
 			}
-		with Not_found ->
-			(* it's an unbound local, let's clone it *)
-			local v
 	in
 	(* use default values for null/unset arguments *)
 	let rec loop pl al first =

+ 3 - 1
typer.ml

@@ -2008,7 +2008,9 @@ and type_ident ctx i p mode =
 				AKExpr (mk (TConst TThis) ctx.tthis p)
 			else
 				let t = mk_mono() in
-				AKExpr (mk (TLocal (alloc_var i t)) t p)
+				let v = alloc_var i t in
+				v.v_meta <- [Meta.Unbound,[],p];
+				AKExpr (mk (TLocal v) t p)
 		end else begin
 			if ctx.curfun = FunStatic && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p;
 			let err = Unknown_ident i in